I am working on a chat application like whatsapp. When the app is running, I use a websocket connection to handle chats between two users however when the app is killed or is not running I tried using FCM push notification service to notify a user for when he gets a message, just like the way whatsapp does.
The problem now is that, FCM receives push notification when the app is in the foreground or in the background(obscured from view, but still in recent task menu), Once the app is swiped out from recent task menu or is not started at all, no notification is received.
I have been stock here for a whole week, I have searched and read through various articles and community conversations on github, stackoverflow, quora and some blog posts and I am yet to find something that works.
I tried to use background services to keep the websocket connection with the server connected but I am been unable to get the service to continue running as android kills off background services when the app is not in the foreground.
I mean how do apps like whatsapp, twitter, instagram, facebook, gmail, likee, tiktok etc handle push notification such that even though the app is closed (swiped out of recent menu or not started at all) it still notifies it's users of some updates on the server.
Here is my code... On the server
const firebase_admin = require('firebase-admin');
var service_account = require('./service_account.json');
firebase_admin.initializeApp({
credential: firebase_admin.credential.cert(service_account),
databaseURL: 'https://fcm_pushnotification-b9983.firebaseio.com/'
});
app.get('/sendPushNotification', (req, res) => {
// This registration token comes from the client FCM SDKs.
var registrationToken = 'clIilmqTRYarMF4gcrpEeH:APA91bFjkmZP7gU836ZCAzyPZaOWU4nU4SLL5OPWNkgukt0zBe0zvn5PEQ-42g60R5UXFN0tXQISjCDcbl032j2Tc81_OZ5uAJ7Aq3_OAaIz7g56oT547LnB9wiiBIKRZhc1TWGMP7lr';
var message = {
notification: {
title: 'Samuel',
body: 'This is an urgent message!',
},
webpush:{
headers:{
Urgency:'high'
}
},
android:{
priority:'high'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
firebase_admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
res.send('Successfully sent message:- '+ response);
})
.catch((error) => {
console.log('Error sending message:- ', error);
res.send('Error sending message:'+ error);
});
});
My services class on android
public class MyFirebaseMessagingService extends FirebaseMessagingService{
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
@Override
public void onNewToken(@NonNull String token) {
Log.d(TAG, "Refreshed token: " + token);
// 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(token);
}
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
this.sendNotification(new Notification(null, title, body, 0));
}
private void sendNotification(Notification notification){
// Notification channel and notification is build here.
}
}
The manifest
<uses-permission android:name="android.permission.INTERNET" />
<service
android:name=".Services.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_heart" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/red" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/notification_channel_id" />
Is there a permission that I need to request for this to work when app is not running. I even set the notification priority as high on the server as can been seen. I have been frustrated by this. Please any help is welcomed.