Hi and thanks for this great library.
I'm in the process of integrating RNFirebase into my project but I hit a roadblock.
I'm currently using another library that also depends on FirebaseMessagingService. Adding the <service> tags to my AndroidManifest.xml causes only one of these subclasses to get called.
What's a good way to handle two libraries that both need to listen to Firebase messages?
I did some research and it turns out there is no way to have two FirebaseMessageService subclasses in the same project.
I solved my own problem by forking the other library and turning their FirebaseMessageService into a hook that I call from my own code.
My own code is a subclass of io.invertase.firebase.messaging.RNFirebaseMessagingService. Here's the sample:
import io.invertase.firebase.messaging.RNFirebaseMessagingService;
public class XXFirebaseMessageService extends RNFirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage message) {
super.onMessageReceived(message);
OtherLibraryWithHooks.getInstance().onMessageReceived(message, this);
}
}
I encountered this case with a marketing tool which has their own notification handlers, so I needed to create another FirebaseMessagingService to handle pushes from that tool and let their SDK handle the payload.
I tried with following custom service but couldn't even see the Log. Only log I get is RNFMessagingService: onMessageReceived event received
public class XFirebaseMessagingService extends RNFirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d("X", "From: " + remoteMessage.getFrom());
Map<String, String> data = remoteMessage.getData();
if(data != null) {
if(data.containsKey("source") && "X".equals(data.get("source"))) {
XTool.get().receive(data);
}
}
}
}
Related AndroidManifest.xml
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".XFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".XFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Any idea why?
Hi @mahyarr @sercanov, 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);
}
}
I've written an article on Medium about this approach: link
Most helpful comment
Hi @mahyarr @sercanov, 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.
I've written an article on Medium about this approach: link