Reputation: 734
I am building a library project in which I have a FirebaseMessagingService. I also have a FirebaseMesagingService in my app. What I see is, whenever an FCM is sent from the server, only one FirebaseMessagingService processes it. This was not the case when I was using GCM Receivers. Both the GCM Receivers used to receive the message and based on message content, they would/would not do anything about it.
How can I achieve the same in FCM.
Upvotes: 13
Views: 6360
Reputation: 71
If you look at the source code of the Android Firebase Messaging, you will see that a broadcast receiver is used to listen for the “com.google.android.c2dm.intent.RECEIVE” event. The old event name from the GCM is also used in Firebase Cloud Messaging. It is possible to have multiple broadcast receivers, so your library can register its receiver in the android manifest:
<application>
<receiver
android:name="com.mylibrary.FirebaseMessagingReceiver"
android:permission="com.google.android.c2dm.permission.SEND"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>
</application>
A broadcast receiver in your library will receive Firebase cloud messages:
class FirebaseMessagingReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
}
}
Upvotes: 1
Reputation: 1308
In such cases, you should make your LibraryFirebaseMessagingService
as parent of your AppFirebaseMessagingService
, and declare only AppFirebaseMessagingService
in app's AndroidManifest.xml
file.
For Example:
in your Library:
public class LibraryFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Your library logic
}
}
Now in your app:
public class AppFirebaseMessagingService extends LibraryFirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(shouldLibraryHandlethis(remoteMessage)) {
super.onMessageReceived(remoteMessage);
} else {
//Your app logic
}
}
}
Now in your app's AndroidManifest.xml
file:
<service
android:name=".AppFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
No need to declare LibraryFirebaseMessagingService
in any AndroidManifest.xml
Upvotes: 1
Reputation: 334
I've got the same issue a few days ago and in our team, we used a slightly different approach which involves reflection.
In general, we use delegate class and provide context via reflection.
public class OwnPushService extends FirebaseMessagingService {
private List<FirebaseMessagingService> messagingServices = new ArrayList<>(2);
public GCPushService() {
messagingServices.add(new AirshipFirebaseMessagingService());
messagingServices.add(new TLFirebaseMessagingService());
}
@Override
public void onNewToken(String s) {
delegate(service -> {
injectContext(service);
service.onNewToken(s);
});
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
delegate(service -> {
injectContext(service);
service.onMessageReceived(remoteMessage);
});
}
private void delegate(GCAction1<FirebaseMessagingService> action) {
for (FirebaseMessagingService service : messagingServices) {
action.run(service);
}
}
private void injectContext(FirebaseMessagingService service) {
setField(service, "mBase", this); // util method for recursive field search
}
}
I've written an article on Medium about this approach if you are interested in the details: link
Upvotes: 2
Reputation: 734
The android app cannot have multiple FirebaseMessagingService as its a service not a receiver. What one can do, is to check two conditions:
If app has FCMMessagingService registered in its functionality, then provide a method in the library project which can take the message as parameter, received by app's FCMMessagingService.
If the app does not have FCM functionality integrated in it, then have FCMMessagingService in your library project which can handle the fcm sent by the server.
Upvotes: 3
Reputation: 1070
Your library's manifest should not have a FirebaseMessagingService subclass. Adding the messa service to the app's manifest should be a part of the integration step, integrating the SDK. Also you should provide a hook in the SDK from where the app can pass the FCM message payload to the SDK.
Essentially if the app does not have its own FirebaseMessagingService subclass it would add your SDK's listener service in the manifest else it will add the hook in its own listener service which passes the payload to your SDK and SDK takes the required action
Upvotes: 6