Flutter/Firebase - How to get "heads up" notification on Android? - firebase

I have a Flutter application using the firebase-messaging plugin for push notifications.
I register firebase like normal on the client, and I send the fcmToken to the server.
Notifications are created via a python server using aiofcm (which uses firebase's XMPP api). They're created like this:
message = aiofcm.Message(
device_token = t2,
notification = {
"title":notification_title,
"body":notification_body,
"sound":"default",
"tag":link
},
data = {
"click_action": "FLUTTER_NOTIFICATION_CLICK"
},
priority=aiofcm.PRIORITY_HIGH
)
await fcm.send_message(message)
On iOS, notifications pop-up at the top of the screen.
On Android, only the icon shows up in the notification tray - not any of the notification content. This is tested on a Pixel 3 and a OnePlus 6, both running Android P.
Ideally, I would like the notification to be "heads-up" style like this:
Before I was able to accomplish this using data messages and creating the notification programmatically in native android, however I would like to avoid that if possible since data messages don't get delivered on Android if the app is terminated.

To Get heads-up - Notification - Kindly set "alert: true"
Example :
notification = {
"title":notification_title,
"body":notification_body,
"sound":"default",
"alert" : true
"tag":link
},

For heads up notification you will need to use flutter_local_notifications Plugin. It is even recommended in FlutterFire official documentation for notification to show notification in foreground (background notification also supported ofcourse!) and it shows heads up notification by default.

You should check out the firebase.flutter.dev docs it shows how to do this easily with the help of flutter_local_notifiation

you can use background fetch and local notification package for background app running.

Related

How to run a function when a notification is received with Firebase Messaging ^8.0.0-dev.8 in Flutter?

Hello I'm using Flutter to build my app and I need to to show an alert whenever a new notification is received.
I've been using firebase_messaging 7.0.3 but I run into an error with onBackgroundMessage. A quick Google search helped me find out that the error I was getting hasn't been fixed yet. However one of the devs posted an update 20 days ago about a new version of the package which fixed that issue.
The new version removed the old onMessage handlers and introduced new ones.
Now they got new event handlers which return streams, but haven't been able to make them fire by using the
.listen() function. Whenever I receive a notification a get a this: D/FLTFireMsgReceiver(22032): broadcast received for message printed in the console but the code in the .listen() doesn't get executed.
Here is a link to an article on Firebase Flutter that is a guide for using the new version of the package.
Here is my code:
...
FirebaseMessaging.onMessage.listen((event) {
// do something
});
FirebaseMessaging.onMessageOpenedApp.listen((event) {
// do something
});
FirebaseMessaging.onBackgroundMessage((message) {
// do something
return;
}
...
A solution I found to get the events to fire was to always call:
await FirebaseMessaging.instance.getToken();
right after the
await Firebase.initializeApp();
Once I call that, the FirebaseMessaging.onMessage.listen catches the event as expected.
I was getting the same log when my app is in doze mode for the Data notification with high priority.
This is because of some issue in the firebase-messaging plugin.
Firebase_messaging plugin internally uses JobIntentService to process background fcm notifications
JobIntentService has one constraint in Android O or later versions, when running a Job it will be subject to standard JobScheduler policies. The job will not run immediately while the device is in doze mode. (reference link)
The same issue was raised in the firebase_messaging git repository(bug link)
Solution
One Signal(another push notification provider) solved this issue by having a modified version of JobIntentService. (OneSignal Solution)
At a high level, it uses wake locks for high priority fcm notifications to run service even in Android O and above.
Add this Pull Request changes in your ide by editing respective files.
TL;DR
Add this Pull Request changes in your ide by editing respective files.
Send Data notification with High priority.
FCM Payload:
{
"message": {
"token": "fcm_client_token",
"data": {
"title": "Hello",
"body": "Test Message"
},
"android": {
"priority": "high"
}
}
}

Firebase messaging failing on flutter after some time

I'm having an issue with FCM on flutter. I have implemented messaging from my server so I'm storing my phone token for each user.
The thing is that when a user logs in for the very first time everything works properly, messages are being sent and user gets notified.
If I do not use the app during the weekend, on Monday I try to send a message by doing some actions on my app but messages are not being sent. I can see my token stored properly in my database.
I'm using firebase_messaging 2.1.0 for flutter.
This is how I get my token
_fireBaseMessaging.getToken().then((token){
_myPhoneToken = token;
});
1-I know token may change when:
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
But none of this happens.
Any advice on how to handle this scenario? thanks in advance.
UPDATE
Provided you have setup the FCM sdk the right way (but you said that it works the fist time you install the app, so I guess so).
Provided that you are sure that the device_token you are using is the one of the device on which you are expecting to receive the notification (check if it's still the same), you should get on this device your notification quite soon if you use "priority" : "high".
{
"to" : "device_token",
"priority" : "high",
"notification" : {
"sound": "default",
"body" : "Test Notification body",
"title": "Test Notification title"
}
}
This method call
_firebaseMessaging.getToken().then((String token)
return always the new token even if it has been updated. So if you print this out on your device and you send a notification on this token without error, there's no reason why you should not get the token if the device has a valid internet connection active.
It's true that the device token can change during time. If you uninstall and reinstall the app, you can see the token will change and if you try to send a notification on the old one, you will get an error.
If instead the token will change during application lifetime, you can be notify on your server side by listening:
_firebaseMessaging.onTokenRefresh.listen((newToken) {
_fcm_token = newToken;
// send the new fcm to your server
});
So first of all I suggest you to be able to send a notification to a device with Postman. Check if the token you are using is still the one on the device. Then you can try to uninstall and reinstall the application and try to use the old token. You will get an error. Then try to send to the new one, and you should get your notification.
Then wait for some days and try again, check if the token has changed or not and if it's not changed you should be able to send the notification without problems with the same token.
Also be aware that data message on Android if the app is terminated are still not supported.
Some networks/router/mobile can cut the connection between firebase library and firebase server due to inactivity (5min without message). This cut may be detected by the library up to 30min (FCM heatbeat interval).
These are some links discussing this issue:
https://github.com/firebase/quickstart-android/issues/307
Android: Delay in Receiving message in FCM(onMessageReceived)
I contacted firebase support but they told that since the issue is caused by external part they cannot fix it (I suggest decreasing heartbeat interval ...)
I fixed it in android using an interval job which apply these instructions:
context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT"));
context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));
You may write this specific code for Android side and should find something similar for ios side.

Single Device Push Notifications (FCM Registration Token) not working

I'm using react-native-firebase with firebase-messaging to implement push notifications.
While I can send push notifications to everyone, I'm unable to send them to individuals. To my knowledge, all I need is the FCM Registration Token which I retrieve by following the documentation
firebase.messaging().getToken()
.then(fcmToken => {
if (fcmToken) {
console.log("fcm token", fcmToken);
} else {
console.log("fcm token", "null");
}
});
The token I receive is a plausible token, but when I copy that token from the logs into the firebase console and try to send it to a single device, nothing is received. (If I push to a user segment, it's received by all devices with the app installed).
As I can not test for iOS, this might or might not also be a problem on iOS.
In my build.gradle file, the firebase relevant libraries are included like so:
compile(project(':react-native-firebase')) {
transitive = false
}
implementation "com.google.android.gms:play-services-base:15.0.1"
implementation "com.google.firebase:firebase-core:16.0.1"
implementation 'com.google.firebase:firebase-auth:16.0.2'
implementation "com.google.firebase:firebase-messaging:17.1.0"
In the MainApplication.java file I add them to the list of ReactPackages.
new RNGoogleSigninPackage(),
new RNFirebasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebaseAuthPackage()
My AndroidManifest does not have any Firebase relevant changes as I discovered that push notifications were working even without them. (While trying to implement push notifications I noticed that all phones were receiving them except the one I was actively working on - so I rolled back the code.)
edit: I managed to receive one single device notification. Without any changes, it was suddenly working exactly once. Now it doesn't work anymore.

Push Notifications on iPhone without alerts to the user

I have searched the web on my question but did not find anyone answering it. This looks weird as I am sure other people face similar issue.
At the moment my app is receiving push notification fine. I have a chat module where user can speak and whenever a new message is being sent, the other phone receive a push notification to update the chat.
You could say no issue there, but the problem is when the user is out of the application: he is still receiving those notifications showing a banner on the screen, and I want to dis-activate this. Basically I want push notification without alerts to the user. Is there a way to do that?
Thanks
Just leave the sound property of your push notification payload empty, omit the alert/text property and add "content-available":1 and your notification will be silent. This is often referred to as silent push notification or "push-to-sync".
See documentation here:
For a push notification to trigger a download operation, the
notification’s payload must include the content-available key with its
value set to 1. When that key is present, the system wakes the app in
the background (or launches it into the background) and calls the app
delegate’s
application:didReceiveRemoteNotification:fetchCompletionHandler:
method. Your implementation of that method should download the
relevant content and integrate it into your app
So your payload should least look like this:
{
"aps" : {
"content-available" : 1,
"sound" : ""
},
"chat-message" : "Hello World!"
}

Push notification with the phonegap - cordova push plugin and pushwoosh.com

I have tested to send push notifications with cordova-1.8.1.js and the push plugin together with pushwoosh.com and it work as it should.
I followed this tutorial: http://www.pushwoosh.com/programming-push-notification/push-notification-sdk-integration-for-phonegap/
The push notification is send to my iPhone and it plays the sound and shows the notification when the phone and app is closed, good!
But if I open the phone when the notification is visible then the app is opened as it should...but
the alert that is displayed is saying:
Alert
"push-notification","{\aps\":\sound\":\"default\",\"alert\":\" and then the message....\"}}”
So what is wrong, it should only write the message in the alert and not the rest?
Also if I delete the app with home button and start it again I get another alert saying "registerDevice", "type":"7".....and so on.
2. How can I make this go away?
Any input appeciated, thanks!
Problem solved. Use this and it will only show the message in the alert and nothing else.
document.addEventListener('push-notification', function(event) {
//console.warn('push-notification!: ' + event.notification);
//navigator.notification.alert(JSON.stringify(['push-notification1!', event.notification]));
var notification = JSON.parse(event.notification);
navigator.notification.alert(notification.aps.alert);
//pushNotification.setApplicationIconBadgeNumber(0);
pushNotification.setApplicationIconBadgeNumber(0);
});

Resources