iOS FCM data only message does not call messaging:didReceiveMessage - firebase

Firebase Messaging version 5.6.0. I am attempting to handle a data only message in the foreground via Firebase Messaging on iOS 9.0 (10 if needed), but it is not calling FIRMessagingDelegate's messaging:didReceiveMessage per the documentation. I see the message come in # FIRMessaging.m's appDidReceiveMessage:message, but never comes through to the delegate.
This is the snippet from the cloud function that sends data to the topic per sending to a topic:
const message = {
data: {
test: '123'
}
topic: 'example'
}
admin.messaging().send(message);
Did I miss something?
Update: I do receive the data if I implement application:didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler.

Thanks to Kat at Firebase support, here is the answer.
Use legacy sendToTopic instead of send, as send quietly adds content_available=1 which gets treated as APNs silent notification. Here is the updated version:
admin.messaging().sendToTopic('example', {
data: {
test: '123'
}
});
// Always use strings for key/values in the data object.
Below verbatim from Kat at Firebase support:
How the FCM data message is handled would depend on your setting for content_available.
If you have content_available = 1, the message is sent via APNs and is treated similar as an APNs silent notification. This is handled in the application:didReceiveRemoteNotification: callback when the app is running in foreground or background (i.e. not killed). See this related StackOverflow post for more information.
Without content_available, the message is sent via FCM direct channel. This only handled in the messaging:didReceiveMessage: when app is in foreground.
Note that messages sent via the Admin SDK's send() method uses the FCM HTTP v1 API which have content_available=1 by default, so they are always sent via APNs. If you want to configure the content_available field, you'll need to use the Admin SDK's sendToDevice() method which uses the legacy protocols.
In addition, here is the list of legacy protocols.

Related

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.

Bluemix Push Notification with userID

I am using the latest Bluemix Push Notification service. I'm using the MFPPush API to register the device (Android).
Here is my code snippet:
var success = function(message)
{
console.log("Success: " + message);
alert("Reg Device: " + message);
};
var failure = function(message)
{
console.log("Error: " + message);
alert("Error: " + message);
};
MFPPush.registerDevice({}, success, failure);
var notification = function(notification)
{
// notification is a JSON object.
alert(notification.message);
};
MFPPush.registerNotificationsCallback(notification);
The success message contains the following information:
Token:APA91bFtkSr59Zxlr52HU****Uij
UserId: ""
DeviceId: g5c6d98f-0867-3fd1-a353-15bcdef675a2
When I send the notification, my device receives the message.
The Swagger REST API shows that I can arbitrarily give some token, userId and deviceId:
{
"deviceId": "TestDeviceId",
"platform": "G",
"token": "************",
"userId": "Joe"
}
How do I get the "TestDeviceId", and how do I get the "token"? I don't see any API to get that information.
Note: You should probably just use the Client SDK to register as it handles all of this in the background--automatically assigning each device a unique ID. You shouldn't explore this unless you know what you're doing. There isn't a really a reason for trying to manually set the deviceID.
When you register a device for the Push Notifications service, you set these values in the body of the POST request. On a successful call, it will return these values in the response. I'll do a demo of this later in the post.
You can also retrieve a list of the device registrations for the Push Notifications service.
You can use that deviceId to retrieved detailed information about the device, send a specific push notification to that device, subscribe it to a tag and send push notifications to those devices, etc.
Swagger Documentation is here.
Regarding those values, you can put whatever you want in them when you register. Typically, these values would be set automatically by the Bluemix Mobile Android/iOS Client SDK when you do the register call. However, you could do this manually using the REST client.
For example:
Here, I'm registering a device:
It registered successfully:
This is what I get if I ask the Push Notifications service for information about my registered devices (for the "deviceId": "arandomdeviceid"):
The Android BMS Core Client SDK sets this deviceId using a unique UUID from the device and hashing it with MD5.
You can look in here more more information about that.
#anamica (a) Allow userId parameter to be passed along with the MFPPush registration like MFPPush.register({"userId": "AUniqueUserId"}, success, failure) (b) Add an additional parameter to the target "userIds" (array).
This enhancement has been done, you can give a try by updating the latest SDK.

Can I add elements to the aps payload sent by the Bluemix IBM Push Notifications service?

I'm successfully using Bluemix Push to send notifications via the REST interface to an iOS app with a simple string alert message. That works fine.
Now I would like to send a more complex message where alert is a dictionary and has a sibling "category" element per The Remote Notification Payload.
Is this possible with Bluemix Push? Whenever I try to deviate from the basic structure, I get "Bad Request - Invalid JSON".
After much head-scratching, I finally picked up a hint from https://www.ng.bluemix.net/docs/services/mobilepush/t_advanced_notifications.html#t_push_badge_sound_payload and figured out that since the category field is unique to APNS, what I needed to send is
"settings" : {
"apns" : {
"category" : "myCategory"
}
#DSchultz_mo I was having issues to find the documentation but I finally found it, so if you go to https://mobile.ng.bluemix.net/imfpushrestapidocs/#/ you can use swagger to register your device and send notification and the magic button is in model there is more details for sendMessageBody

Invalid tag for push notifications in Windows Azure

I am building a Windows Phone 8.1 application and want to add push notifications from Windows Azure. I am creating the channel by using CreatePushNotificationChannelForApplicationAsync, after which I take the resulting URI and store it in the Azure database. When trying to send a push notification by using push.wns.sendToastText01, I get the following error in the Azure logs:
Error in script '/table/Message.insert.js'. Error: 400 - An invalid tag 'https://db3.notify.windows.com/?token=AwYAAAC3tTi3W5ItZ0hWdZ3FLmELt%2flHcwpsM...' was supplied. Valid tag characters are alphanumeric, _, #, -, ., : and #.
I noticed that the channel URI contains the '%' which does not appear among the valid characters, yet that is the URI that gets generated in the client application. Am I using a wrong method for sending push notifications or is there something else I am missing?
Edit: I am using Node.js for backend in Azure.
request.execute({
success: function() {
push.wns.sendToastText01(channelUri, {
text1: "Google Plus Friend Tracker",
text2: item.content,
param: '/ChatPage.xaml?friendGoogleId=' + item.author_id
})
}
});
Looking at the wns object documentation, the first parameter would be the tags that you are sending to. Since you're providing a channel in the code above, you are getting the error specified.
The backend does not need to provide the channel URI, as this was associated with the Notification Hub via the client-side registration action. If you are broadcasting the message, you would just provide null as the tag value. Otherwise, you can use the tags that were specified when you registered the channel URI.
For more about the process, see the "Get started with push" tutorial. There is also an example of using a tag (user ID) in the "Send push notifications to authenticated users" tutorial. For more on tags in general, the Notification Hubs breaking news tutorial is also good.

Resources