Googleplayservicescomponents: Firebase Messaging not working with Xamarin.Forms

Created on 5 Sep 2016  路  15Comments  路  Source: xamarin/GooglePlayServicesComponents

Xamarin.Android

Version 6.0

Operating System & Version :

Mac OSX 10.10.5

Describe your Issue:

installed "Xamarin Firebase - Messaging 32.4.0-beta2" in my droid project. I get the token, but my services are never called. I want to use it for Push notification.

Here is my MainActivity:

   protected override void OnCreate (Bundle bundle)
   {
    base.OnCreate (bundle);

    global::Xamarin.Forms.Forms.Init (this, bundle);

    var options = new FirebaseOptions.Builder()
        .SetApplicationId(ApplicationId)
        .SetApiKey(ApiKey)
        //.SetDatabaseUrl("Firebase-Database-Url")
        .SetGcmSenderId(GcmSenderId)
        .Build();

    var firebaseApp = FirebaseApp.InitializeApp(this, options);
    // Generate token in background thread
    Task.Run (() => {
        var instanceID = FirebaseInstanceId.Instance;
        instanceID.DeleteInstanceId ();
        var iid1 = instanceID.Token;
        var iid2 = instanceID.GetToken (GcmSenderId, Firebase.Messaging.FirebaseMessaging.InstanceIdScope);
        Console.WriteLine( "Iid1: {0}, iid2: {1}", iid1, iid2);
    });

    LoadApplication (new App ());

}

Services:

[Service]
[IntentFilter (new [] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";

public override void OnTokenRefresh ()
{
    // Get updated InstanceID token.
    var refreshedToken = FirebaseInstanceId.Instance.Token;
    Android.Util.Log.Debug (TAG, "Refreshed token: " + refreshedToken);

    // TODO: Implement this method to send any registration to your app's servers.
    SendRegistrationToServer (refreshedToken);
}
// [END refresh_token]

void SendRegistrationToServer (string token)
{
    // Add custom implementation, as needed.
}
}

[Service]
[IntentFilter (new [] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";

public override void OnMessageReceived (RemoteMessage message)
{
    Android.Util.Log.Debug (TAG, "From: " + message.From);
    Android.Util.Log.Debug (TAG, "Notification Message Body: " + message.GetNotification ().Body);
}

void SendNotification (string messageBody)
{
    var intent = new Intent (this, typeof (MainActivity));
    intent.AddFlags (ActivityFlags.ClearTop);
    var pendingIntent = PendingIntent.GetActivity (this, 0 /* Request code */, intent, PendingIntentFlags.OneShot);

    var defaultSoundUri = RingtoneManager.GetDefaultUri (RingtoneType.Notification);
    var notificationBuilder = new NotificationCompat.Builder (this)
        .SetContentTitle ("FCM Message")
        .SetContentText (messageBody)
        .SetAutoCancel (true)
        .SetSound (defaultSoundUri)
        .SetContentIntent (pendingIntent);

    var notificationManager = NotificationManager.FromContext (this);

    notificationManager.Notify (0, notificationBuilder.Build ());
}
}

Any guidance / thoughts on this?
Thanks

Most helpful comment

Finally figured this out.

It looks like Google changed a couple base types of their broadcast receivers in the Firebase Messaging library. They used subclass BroadcastReceiver and now are instead subclassing WakefulBroadcastReceiver.

We used to merge in the attributes from the partial class declarations in our bindings, however this doesn't seem to work when the class is not directly subclassing BroadcastReceiver, so the receiver definitions were not making it into the final application's AndroidManifest.xml file.

The work around for now is to manually add these declarations to your AndroidManifest.xml file:

<!-- put this inside your application element -->
<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>

All 15 comments

Any updates on this? I'm having the exact same problem along with other people in this thread: https://forums.xamarin.com/discussion/70248/firebase-configuration/p2

Finally figured this out.

It looks like Google changed a couple base types of their broadcast receivers in the Firebase Messaging library. They used subclass BroadcastReceiver and now are instead subclassing WakefulBroadcastReceiver.

We used to merge in the attributes from the partial class declarations in our bindings, however this doesn't seem to work when the class is not directly subclassing BroadcastReceiver, so the receiver definitions were not making it into the final application's AndroidManifest.xml file.

The work around for now is to manually add these declarations to your AndroidManifest.xml file:

<!-- put this inside your application element -->
<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>

Yeh just checked that and its working fine now. Thanks!

Hey guys, I have one problem yet.
When my app is in background or closed, i can't manage my notification, i already checked it if exists any data in my Intent.Extras, but is always null and OnMessageReceived never is called.
Can you help me? Thanks!

Hi @leosoareslima, i had the same problem in a pure Android app few days ago.
Problem is not from Xamarin, but from Firebase. The library does not fire the method when background. Instead, it puts a tray icon and when clicked it open the main page. There you have to manage the message.

@softsan did you was able to use this "Xamarin Firebase - Messaging 32.4.0-beta2" with Xamarin forms? if so, how did you added the packages?, I'm stuck with dependancies Xamarin.Forms, Xamarin.Android.Support, and Xamarin.GooglePlayServices

@softsan , i have the same problem when adding package to xamarin.forms apps mentionned by @MCvel . Could you please give us how did you do it!
thks,

@MCvel and @zmarwa I simply created a new project. update my xamarin.forms nuget package and then added firebase related nuget. Below is my package.config file:

<packages>
  <package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.Design" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.v4" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.v7.AppCompat" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.v7.CardView" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.v7.MediaRouter" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.v7.RecyclerView" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Android.Support.Vector.Drawable" version="23.3.0" targetFramework="MonoAndroid60" />
  <package id="Xamarin.Firebase.Common" version="32.940.0-beta3" targetFramework="monoandroid70" />
  <package id="Xamarin.Firebase.Iid" version="32.940.0-beta3" targetFramework="monoandroid70" />
  <package id="Xamarin.Firebase.Messaging" version="32.940.0-beta3" targetFramework="monoandroid70" />
  <package id="Xamarin.Forms" version="2.3.2.127" targetFramework="monoandroid70" />
  <package id="Xamarin.GooglePlayServices.Basement" version="32.940.0-beta3" targetFramework="monoandroid70" />
  <package id="Xamarin.GooglePlayServices.Tasks" version="32.940.0-beta3" targetFramework="monoandroid70" />
 </packages>

Hope this helps.

@zmarwa and @MCvel if you don't want to create a new project, Xamarin.Forms 2.3.3.175 works fine with Xamarin.Firebase.Messaging 32.940.0 -beta3, I needed to install this one to get it working without creating an new project or deleting and updating all packages, but I'm facing the same problem reported in this topic. I have the token but my notification sent by Firebase Console doesn't arrive :(

I have the problem that messages only arrive randomely. Sometimes they do without any problems but then no message at all arrives.
Any Idea where to look?

I have created a following workaround for implementing FCM in android project under Xamarin Forms. Actually Firebase library cannot be installed in Xamarin forms due to version conflict of Android Support lib. Please take a look at the following workaround

https://forums.xamarin.com/discussion/89731/how-to-implement-fcm-in-xamarin-forms/p1?new=1

I have implemented the functionality but I am unable to get push notification can anyone help in this issue

@softsan @Redth My question for you: must I always call the _DeleteInstanceId()_ method (forcing OnRefreshToken() callback) to initialize the InstanceID service (as suggested in the code posted here, but also in other xamarin-comments) every time the App is starting up ?
For my experience: yes, I have to reset InstanceId, (but this contradicts, in my opinion, the operating logic of the class InstanceID), because this is the only way to (ALWAYS) obtain a valid token from the FCM Server; otherwise, after some time (expecially after closing and rebooting the APP), using the token returned by Instance.Token or by instanceID.GetToken (each time the same id) , the FCM Server (I'm using the notifications console) report this error: 'Registration token not registered'

firebaseerror

About tokens expiration, the Firebase tutorial (https://firebase.google.com/docs/cloud-messaging/android/first-message) explains that:
_The registration token may change when:
The app deletes Instance ID
The app is restored on a new device
The user uninstalls/reinstall the app
The user clears app data._

So, should be the IstanceID Service that must refresh the token when necessary (rarely) (?).

Can you confirm the right way to initialize the InstanceId service of FCM (instanceID.DeleteInstanceId() must be called or not) ?

@softsan @sylmoss do you add the packages to the Xamarin.Forms's files, meaning their is a universal package for them? I have already added Firebase.Auth to both my android and ios projects, but want to use forms to make both ios and android log in pages. I

@runawayGoblin- There are ways to implement. If you want to use firebase login with Xam forms you can approach for custom renderer or Dependency service to implement platform side functionality i think.

Hope it helps.

Was this page helpful?
0 / 5 - 0 ratings