Hello colleagues. In this article, I want to introduce you to Firebase notification implementation. It's a super easy realization and I show how.
Creating Firebase project
Go to the https://console.firebase.google.com and click on the huge + and begin creating a project.
Let's name the project "push-maui". Click "Continue".
In the second step leave it unchanged.
In the last step select an account and click "Create project".
After one minute - click "Continue".
Creating MAUI project
Let's create a new project:
dotnet new maui -n PushMauiSample
cd PushMauiSample
Open the solution in your favorite IDE. Before we begin implementing Firebase Cloud Messaging, let's add Plugin.Firebase
package. I install an older version since it is compatible with JDK. The newest version has issues:
dotnet add package Plugin.Firebase 1.2.0
And also, for Android you need these packages:
dotnet add package Xamarin.Kotlin.StdLib.Jdk7
dotnet add package Xamarin.Kotlin.StdLib.Jdk8
Further, go to the PushMauiSample.proj
, delete all non-android settings, and inject Google services. It should be something like that:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0-android</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>PushMauiSample</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Display name -->
<ApplicationTitle>PushMauiSample</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.pushmauisample</ApplicationId>
<ApplicationIdGuid>d0db7add-d444-449e-bb11-c0ff3569174c</ApplicationIdGuid>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />
<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
<GoogleServicesJson Include="google-services.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Plugin.Firebase" Version="1.2.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
<PackageReference Include="Xamarin.Kotlin.StdLib.Jdk7" Version="1.8.22" />
<PackageReference Include="Xamarin.Kotlin.StdLib.Jdk8" Version="1.8.22" />
</ItemGroup>
<ItemGroup>
<MauiPlatformSpecificFolder Remove="Platforms\iOS\" />
<MauiPlatformSpecificFolder Remove="Platforms\MacCatalyst\" />
<MauiPlatformSpecificFolder Remove="Platforms\Tizen\" />
<MauiPlatformSpecificFolder Remove="Platforms\Windows\" />
</ItemGroup>
</Project>
After that, you did it. Let's register the service. Add this code to MauiProgram.cs
:
private static MauiAppBuilder RegisterFirebaseServices(this MauiAppBuilder builder)
{
builder.ConfigureLifecycleEvents(events =>
{
events.AddAndroid(android => android.OnCreate((activity, state) =>
CrossFirebase.Initialize(activity, CreateCrossFirebaseSettings())));
});
builder.Services.AddSingleton(_ => CrossFirebaseAuth.Current);
return builder;
}
private static CrossFirebaseSettings CreateCrossFirebaseSettings()
{
return new CrossFirebaseSettings(isAuthEnabled: true, isCloudMessagingEnabled: true);
}
And sure, you should update this method:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.RegisterFirebaseServices()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
return builder.Build();
}
Registering an application
And now, let's return to Firebase Console and register the application. You should choose Android.
There are four steps. The more important is first. The Android package name is project id. Let's name it dev.to.android.push
. Click the Register app.
In the next step, save google-services.json
to the root of your project. Click Next.
The next steps without changes. In the end, click "Continue to console".
A few settings and implementation
Let's return to PushMauiSample.proj
and find this row:
<ApplicationId>com.companyname.pushmauisample</ApplicationId>
You should replace to dev.to.android.push
name that we registered in the Firebase console. The same name you can find in google-services.json
file. This name should identical.
Next, go to the MainPage.xaml
and paste this code in VerticalStackLayout block:
<Image
HeightRequest="200"
HorizontalOptions="Center"
SemanticProperties.Description="Cute dot net bot waving hi to you!"
Source="dotnet_bot.png" />
<Label
FontSize="32"
HorizontalOptions="Center"
SemanticProperties.HeadingLevel="Level1"
Text="Hello, Firebase notifications" />
<Label
FontSize="18"
HorizontalOptions="Center"
SemanticProperties.Description="Welcome to dot net Multi platform App U I"
SemanticProperties.HeadingLevel="Level2"
Text="Welcome to .NET Multi-platform App UI" />
<Button
Clicked="GetTokenClicked"
HorizontalOptions="Center"
SemanticProperties.Hint="Get registration id token"
Text="Get Token"
x:Name="CounterBtn" />
After that, you should create an event handler like this:
private async void GetTokenClicked(object sender, EventArgs e)
{
await CrossFirebaseCloudMessaging.Current.CheckIfValidAsync();
var token = await CrossFirebaseCloudMessaging.Current.GetTokenAsync();
Token = token;
await DisplayAlert("FCM token", token, "OK");
}
And don't forget to add a property for keeping token:
public string Token { get; set; }
The first part is ready. Let's check out it.
We got a token that was registered in Firebase. Without this token, you can't send notifications.
Implementing sending notifications
And now, we need to configure sending notifications.
Let's return to the Firebase console again and find gears. Select the "Project settings" and "Service accounts" tab. Click "Generate new private key."
Save it to your project into Resources/Raw
folder with name firebase-adminsdk.json
.
After that return to MainPage.xaml
and add the button:
<Button
Clicked="SendPushClicked"
HorizontalOptions="Center"
SemanticProperties.Hint="Send notification"
Text="Send push"
x:Name="SendPush" />
Add handler to MainPage.cs
. Here it loads the file sdk settings and creates an application that sends a notification:
private async void SendPushClicked(object sender, EventArgs e)
{
var app = FirebaseApp.Create(new AppOptions
{
Credential = await GetCredential()
});
FirebaseMessaging messaging = FirebaseMessaging.GetMessaging(app);
var message = new Message()
{
Token = Token,
Notification = new Notification { Title = "Hello world!", Body = "It's a message for Android with MAUI"},
Data = new Dictionary<string, string> {{"greating", "hello"}},
Android = new AndroidConfig { Priority = Priority.Normal},
Apns = new ApnsConfig { Headers = new Dictionary<string, string> { {"apns-priority", "5"}}}
};
var response = await messaging.SendAsync(message);
await DisplayAlert("Response", response, "OK");
}
private async Task<GoogleCredential> GetCredential()
{
var path = await FileSystem.OpenAppPackageFileAsync("firebase-adminsdk.json");
return GoogleCredential.FromStream(path);
}
You'll see a lot of unresolved code, it means you need the FirbaseAdminCore
package:
dotnet add package FirbaseAdminCore
After installing your code will resolved. And naw became time check out our application.
Getting token:
Sending push:
Finally, we got the notification:
Conclusion.
It's an easy way to make notifications for mobile devices. Put likes on and subscribe. Happy coding!
Source code here.
Top comments (8)
WHAT A FKNG NONSENSE! Really!? Need internet to be able to show some crappy notification to a phone!!? This is the worst aprouch ever created. Also why in the hell you privide maybe sensetive data to 3rd party??? why google or whoever owns firebase, send data? TERRIBLE IDEA!!
You need to grab ASAP a manual because you don't seem to know the difference between local and remote (push notifications) and what are they used for.
In remote notifications you have to send this data to third parties. FCM in case of Android and APS in case of iOS. Those services are in charge of sending the notification to the device or group of devices. So yes, you need internet in this case.
If you just want your application to be able to generate notifications when something happens, you should take a look into local notifications. To generate local notifications you won't need internet connection.
Hi Serhii,
Excellent post and work! Thank you very much.
I get everything working right but the Push notification doesn't arrive. I get a warning about the Channel being Null.
Developer warning for package "xxx.xxx.xxx". Failed to post notification on channel "null". See log for more details.
Is there anyway you can help?
Also, have you created an iOS version of your solution?
Thanks again!
Vasilis
I hadn't created it for iOS since I don't have an Apple Developer account. Likely, iOS requires additional settings. It needs investigating. I recalled why I didn't make it for iOS. I was having issues with packages. For this reason, I refused the idea. The iOS is capricious.
Thanks for your immediate reply.
How about the issue with the channel? Have you managed to reproduce it and maybe solve it?
Hi Serhii
Just pulled you repo and replaced google-services.json and firebase-adminsdk.json
and ran dotnet restore
But I then get this, while trying the get token:
Java.Lang.IllegalStateException: 'Default FirebaseApp is not initialized in this process dk.xxxx.mobile. Make sure to call FirebaseApp.initializeApp(Context) first.'
Any help is appreciated
Check all settings it should work fine. I just checked this out and I didn't find any issues. Or describe your issue in more detail. Make steps to reproduce.
HI, I had a same problem. I think you have to change google-services.json build action.** RMB on google-services.json => Property => Build Action => Select GoogleServiceJson**