Last active
          May 19, 2025 17:53 
        
      - 
      
- 
        Save svedmark/e71d319590340a75374c3b9b62c564d9 to your computer and use it in GitHub Desktop. 
    Minimal FCM Push Messaging for .NET MAUI (RC3)
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | * Setup Firebase project like normal and add google-services.json (make sure Build action is set to GoogleServicesJson) | |
| * Nugets required for MAUI project file: (later versions don't work) | |
| <ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'"> | |
| <PackageReference Include="Xamarin.Firebase.Iid" Version="121.1.0" /> | |
| <PackageReference Include="Xamarin.Firebase.Messaging" Version="122.0.0" /> | |
| <PackageReference Include="Xamarin.Google.Dagger" Version="2.39.1" /> | |
| <PackageReference Include="Xamarin.GooglePlayServices.Base" Version="117.6.0.5" /> | |
| </ItemGroup> | |
| * Also add the receiver configuration to the app manifest's application node: | |
| <receiver | |
| android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" | |
| android:exported="false" /> | |
| <receiver | |
| android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" | |
| android:exported="true" | |
| android:permission="com.google.android.c2dm.permission.SEND"> | |
| <intent-filter> | |
| <action android:name="com.google.android.c2dm.intent.RECEIVE" /> | |
| <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> | |
| <category android:name="${applicationId}" /> | |
| </intent-filter> | |
| </receiver> | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | using Android.App; | |
| using Android.Content; | |
| using AndroidX.Core.App; | |
| using Firebase.Messaging; | |
| namespace FCMApp.Android; | |
| [Service(Exported = false)] | |
| [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] | |
| public class FCMService : FirebaseMessagingService | |
| { | |
| public override void OnMessageReceived(RemoteMessage message) | |
| { | |
| RemoteMessage.Notification notification = message.GetNotification(); | |
| IDictionary<string, string> data = message.Data; | |
| string body = ""; | |
| string title = ""; | |
| if (data != null && data.ContainsKey("body") && data.ContainsKey("title")) | |
| { | |
| body = data["body"]; | |
| title = data["title"]; | |
| } | |
| else if (notification != null) | |
| { | |
| body = message.GetNotification().Body; | |
| title = message.GetNotification().Title; | |
| } | |
| if (!string.IsNullOrEmpty(body) && !string.IsNullOrEmpty(title)) | |
| { | |
| // TODO: Manage this message (we get here only when app is in foreground) | |
| } | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | namespace FCMApp; | |
| public interface IMessagingService | |
| { | |
| string GetToken(); | |
| bool IsMessagingAvailable(); | |
| void SetNewTokenCallback(Action<string> token_callback); | |
| } | |
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | using Android.App; | |
| using Android.Content.PM; | |
| using Android.OS; | |
| using Android.Util; | |
| namespace FCMApp; | |
| [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] | |
| public class MainActivity : MauiAppCompatActivity | |
| { | |
| static readonly string TAG = "MainActivity"; | |
| public static readonly string CHANNEL_ID = "main_channel"; | |
| public static readonly int NOTIFICATION_ID = 100; | |
| protected override void OnCreate(Bundle savedInstanceState) | |
| { | |
| base.OnCreate(savedInstanceState); | |
| // handle incoming intent extras (when clicking on a push notification) | |
| if (Intent.Extras != null) | |
| { | |
| foreach (var key in Intent.Extras.KeySet()) | |
| { | |
| var value = Intent.Extras.GetString(key); | |
| Log.Debug(TAG, "Key: {0} Value: {1}", key, value); | |
| } | |
| } | |
| CreateNotificationChannel(); | |
| } | |
| void CreateNotificationChannel() | |
| { | |
| // notification channel mandatory only from API 26 | |
| if (Build.VERSION.SdkInt < BuildVersionCodes.O) | |
| return; | |
| NotificationManager mgr = (NotificationManager)GetSystemService(NotificationService); | |
| mgr.CreateNotificationChannel( | |
| new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default) | |
| { | |
| Description = "Firebase Cloud Messages appear in this channel" | |
| }); | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | using Android.Gms.Common; | |
| using Android.Gms.Tasks; | |
| using Firebase.Iid; | |
| namespace FCMApp; | |
| public partial class MessagingService | |
| { | |
| public partial bool IsMessagingAvailable() => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Android.App.Application.Context) == ConnectionResult.Success; | |
| public partial string GetToken() => FirebaseInstanceId.Instance.Token; | |
| public partial void SetNewTokenCallback(Action<string> token_callback) | |
| { | |
| if (token_callback == null) | |
| throw new InvalidOperationException("Callback cannot be null"); | |
| if (GetToken() != null) | |
| token_callback(GetToken()); | |
| else | |
| FirebaseInstanceId.Instance.GetInstanceId().AddOnSuccessListener(new OnTokenListener((token) => token_callback(token))); | |
| } | |
| } | |
| public class OnTokenListener : Java.Lang.Object, IOnSuccessListener | |
| { | |
| Action<string> _callback; | |
| public OnTokenListener(Action<string> success_callback) => _callback = success_callback; | |
| public void OnSuccess(Java.Lang.Object result) => _callback?.Invoke(FirebaseInstanceId.Instance.Token); | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | namespace FCMApp; | |
| public partial class MessagingService : IMessagingService | |
| { | |
| public partial string GetToken(); | |
| public partial bool IsMessagingAvailable(); | |
| public partial void SetNewTokenCallback(Action<string> token_callback); | |
| } | 
hi,
this line: public partial bool IsMessagingAvailable() => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Android.App.Application.Context) == ConnectionResult.Success;
Android.App.Application.Context not found ind project with .NET9.0,
how to solved it.
thanks,
Carlos.
hi,
[SOLVED]
public partial bool IsMessagingAvailable() => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable( Microsoft.Maui.ApplicationModel.Platform.CurrentActivity) == ConnectionResult.Success;
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
            
Thanks for sharing, however methods are not hitting, could you please share working example code?