Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to extend FirebaseInstanceIdService to subscribe to FCM Topics?

I want to manage topic subscription from the client (android app). I am currently doing it at activity onCreate(). I am wondering if the right way is to subscribe / unsubscribe at InstanceIdService::onTokenRefresh() or at any time convenient (on button click, etc).

In short, if I manage topic subscription at the client side (no server), do I still have to bother with InstanceIdService?

Different sources of documentation provide different take on Firebase Cloud Messaging (FCM) topic subscription. Some mention InstanceIdService, some not. Here they are:

  1. Firebase Guide on Send Topic Messages with Firebase Console

It does not mention InstanceIdService when talking about topic subscriptions.

Once you've completed the setup tasks, you can add client code to subscribe to a topic and then handle messages sent to the topic.

Client apps can subscribe to any existing topic, or they can create a new topic. When a client app subscribes to a new topic name (one that does not already exist for your Firebase project), a new topic of that name is created in FCM and any client can subsequently subscribe to it.

To subscribe to a topic, the client app calls Firebase Cloud Messaging subscribeToTopic() with the FCM topic name:

FirebaseMessaging.getInstance().subscribeToTopic("news");
  1. Firebase Android Codelab

The class MyFirebaseInstanceIdService will be a service used to handle FCM logic. This service is used to alert the application when a new InstanceID token is generated, and to retrieve the generated token.

Modify it to extend FirebaseInstanceIdService and override the onTokenRefresh method to subscribe to a topic. Use the following code to update the onTokenRefresh method in MyFirebaseInstanceIdService to look like this:

public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {

   private static final String TAG = "MyFirebaseIIDService";
   private static final String FRIENDLY_ENGAGE_TOPIC = "friendly_engage";

   /**
    * The Application's current Instance ID token is no longer valid 
    * and thus a new one must be requested.
    */
   @Override
   public void onTokenRefresh() {
       // If you need to handle the generation of a token, initially or
       // after a refresh this is where you should do that.
       String token = FirebaseInstanceId.getInstance().getToken();
       Log.d(TAG, "FCM Token: " + token);

       // Once a token is generated, we subscribe to topic.
       FirebaseMessaging.getInstance()
               .subscribeToTopic(FRIENDLY_ENGAGE_TOPIC);
   }
}
  1. Firebase quickstart project on github

It uses InstanceIdService, but topic subscription does not happen there. It is done simply in client as part of button click in an activity:

Button subscribeButton = (Button) findViewById(R.id.subscribeButton);
subscribeButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // [START subscribe_topics]
        FirebaseMessaging.getInstance().subscribeToTopic("news");
        // [END subscribe_topics]

        // Log and toast
        String msg = getString(R.string.msg_subscribed);
        Log.d(TAG, msg);
        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
    }
});

The comment at InstanceIdService code suggests to manager subscription onTokenRefresh()

@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // Instance ID token to your app server.
    sendRegistrationToServer(refreshedToken);
}
like image 581
rpattabi Avatar asked Oct 19 '16 10:10

rpattabi


People also ask

How to subscribe topic FCM Android?

When a client app subscribes to a new topic name (one that does not already exist for your Firebase project), a new topic of that name is created in FCM and any client can subsequently subscribe to it. To unsubscribe, the client app calls Firebase Cloud Messaging unsubscribeFromTopic() with the topic name.

How FCM works in Android?

The FCM backend receives the message request, generates a message ID and other metadata, and sends it to the platform specific transport layer. When the device is online, the message is sent via the platform-specific transport layer to the device. On the device, the client app receives the message or notification.

What is Cloud messaging API in Android?

Google Cloud Messaging (GCM) for Android is a service that allows you to send data from your server to your users' Android-powered device and also to receive messages from devices on the same connection.

When was Firebase Cloud messaging released?

Firebase Cloud Messaging is a cross-platform messaging solution on which the user can deliver messages without cost. FCM is compatible with various platforms including Android and iOS. Google launched support for web applications on October 17, 2016 including mobile web application.


1 Answers

As you already know, FirebaseInstanceId is probably a singleton class, where you retrieve your registration token. So I think the subscribeToTopic() method, since only the name of the topic is passed, you can presume that it already calls an instance of the FirebaseInstanceId itself or then just send in a request towards the FCM servers with the corresponding registration token and the topic it should be subscribed to.

Long story short, I don't think it's a requirement for you to extend the FirebaseInstanceIdService to call subscribeToTopic(), however, I think it's essential because (as described in the docs) it is the:

Base class to handle Firebase Instance ID token refresh events.


For your other inquiries.

I want to manage topic subscription from the client (Android app). I am currently doing it at activity onCreate(). I am wondering if the right way is to subscribe / unsubscribe at InstanceIdService::onTokenRefresh() or at any time convenient (on button click, etc)?

I think doing it in onCreate() is okay. If you see my answer here, @FrankvanPuffelen mentioned:

subscribing to topics on app start is fine.

However, I think it's also good to add in a subscribeToTopic() call in onTokenRefresh(), so that as soon as a new token is provided for the app instance, you'll immediately subscribe it accordingly.

Note that behavior I'm thinking here is that when a registration token is invalidated, it's subscription is also lost and that adding subscribeToTopic() in onRefreshToken() will immediately re-subscribe them for you (of course this still depends in your implementation on which topic you want to subscribe it).

like image 120
AL. Avatar answered Oct 12 '22 11:10

AL.