I am working on a chat application and I have successfully integrated Firebase in my iOS app. And now, Firebase Notifications is not clear to me. I have setup everything properly as per the documentation, and now I am getting notification to my device when I send notification from the Firebase Console. I want to know how Firebase will handle or send notification to a particular user. Do we need to send device info to Firebase? Or how does it work?
I want to know how Firebase will handle or send notification to a particular user.
The Firebase Server acts as a middle-man that handles the queuing of your messages.
For example, for Downstream Messaging, you send a push notification from your App Server or using the Firebase Console, the message is delivered to the FCM Server, storing it until such time that the device it has to send it to is available to receive it (or until such time you want it to be delivered, see Lifetime of a Message).
You can check out this Lifecycle Flow of GCM (since I think for this part, it's still the same for FCM):
Lifecycle Flow
Send and receive downstream messages.
Send a message. The app server sends messages to the client app:
The app server sends a message to GCM connection servers.
The GCM connection server enqueues and stores the message if the device is offline.
When the device is online, the GCM connection server sends the message to the device.
On the device, the client app receives the message according to the platform-specific implementation. See your platform-specific documentation for details.
Receive a message. A client app receives a message from a GCM connection server.
Note that this the one I mentioned is only for Downstream Messaging. You can check out the docs if you're also interested to learn about the flow for Upstream Messaging.
Do we need to send device info to Firebase?
It depends on your use-case. Although I think it is highly advisable for you to store all the registration tokens for future use.
Or how does it work?
Besides from what I already mentioned above, I'm just gonna go ahead and quote the How does it work? from the official docs:
How does it work?
An FCM implementation includes an app server that interacts with FCM via HTTP or XMPP protocol, and a client app. You can compose and send messages using the app server or the Notifications console.
Firebase Notifications is built on Firebase Cloud Messaging and shares the same FCM SDK for client development. For testing or for sending marketing or engagement messages with powerful built-in targeting and analytics, you can use Notifications. For deployments with more complex messaging requirements, FCM is the right choice.
I recently ran into the same problem when dealing with FCM.
You need to set both data and notification objects in your message payload like it is described here.
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications
Messages with both notification and data payloads
App behavior when receiving messages that include both notification
and data payloads depends on whether the app is in the background or
the foreground—essentially, whether or not it is active at the time of
receipt.
When in the background, apps receive the notification payload in the
notification tray, and only handle the data payload when the user taps
on the notification. When in the foreground, your app receives a
message object with both payloads available. Here is a JSON-formatted
message containing both the notification key and the data key:
{
"to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
Also, you need to set high priority if you want to deliver push notifications on the device.
https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message
Setting the priority of a message
You have two options for assigning delivery priority to downstream
messages: normal and high priority. Delivery of normal and high
priority messages works like this:
Normal priority. This is the default priority for message delivery.
Normal priority messages won't open network connections on a sleeping
device, and their delivery may be delayed to conserve the battery. For
less time-sensitive messages, such as notifications of new email or
other data to sync, choose normal delivery priority.
High priority
FCM attempts to deliver high priority messages immediately, allowing
the FCM service to wake a sleeping device when possible and open a
network connection to your app server. Apps with instant messaging,
chat, or voice call alerts, for example, generally need to open a
network connection and make sure FCM delivers the message to the
device without delay. Set high priority only if the message is
time-critical and requires the user's immediate interaction, but
beware that setting your messages to high priority contributes more to
battery drain compared with normal priority messages. Valid values are
normal and high. For more details, see the server reference for HTTP
or XMPP.
For iOS client apps, normal and high priority are analogous to APNs
priority levels 5 and 10. For full details on iOS-specific behavior,
see the APNs documentation. For details on Android-specific behavior,
see Optimizing for Doze and App Standby.
Here is an example of a normal priority message to notify a magazine
subscriber that new content is available to download:
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"priority" : "high",
"notification" : {
"body" : "This week's edition is now available.",
"title" : "NewsMagazine.com",
"icon" : "new"
},
"data" : {
"volume" : "3.21.15",
"contents" : "http://www.news-magazine.com/world-week/21659772"
}
}
You don't need to send anything to Firebase if you have successfully configured your project for Firebase.
https://firebase.google.com/docs/cloud-messaging/ios/client
Related
For regular single-device push notifications through APNS, less important pushes can "replace" more important ones, because if the device is temporarily offline, only the last notification per device/app is retained and delivered with APNS.
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW5
Let's say I'm delivering critical pushes to single devices, and informational, non-critical pushes via a topic-based pushes in Firebase FCM. Would it still be true that the topic-based pushes could replace the critical pushes for an offline device?
A predecessor of mine left behind a design document that said topic-bases push subscriptions would avoid the problem of informational pushes replacing critical ones, but I haven't found any documentation to support that. I'm thinking I might be better off using websockets or similar (maybe via PubNub) for the the informational pushes when the app is in the foreground, and only use APNS/FCM for the critical pushes. Am I right?
disclaimer: this does not directly address the Firebase topic-based aspect of
this question, rather, it provides an alternative solution that has
the same features/implementation for both FCM and APNs with respect to QoS, or more specifically, the ability to retrieve messages that might have been missed while offline.
Publish, Persist & Push with PubNub
PubNub Storage Service
Well, putting APNs and FCM aside, PubNub will persist all of your messages for later retrieval when you enable the Storage service. So when devices are offline, they can receive push notifications (APNs/FCM), and whether or not those notifications are received/acknowledged by the end-user, your app can easily retrieve all messages that were sent while the device was offline.
PubNub Mobile Push Service
The other advantage of using PubNub is that you include the APNs/FCM push payloads in the realtime publish payload and if the device is active/online and subscribed to that channel, then it receives the message in realtime. If the device is not subscribed to the channel, it still receives the FCM/APNs push notification.
NOTE: you must enable the Storage service on your PubNub key set and
configure the retention as required: 1 day, 3 days, ... 30 days or
Unlimited.
I used FCM for topic messaging with silent notification.
I have android and iOS app.
This is the sample JSON that I used in PHP
{
"to" : "/topics/mytopic",
"priority": "high",
"content_available": true,
"data" : {
"<key>" : "<string>",
"<key2>" : "<string>"
}
I subscripted the same topic with android and iOS, then send to both.
iOS part always lost some messages
EX:
Send 10 messages
android: 10
iOS: 8
I searched the web and only found if battery level is less than 20% it will lost message.
(I test this behavior it's really happened, but not related to my cases. My battery level is always high in my test cases)
I have some questions, can someone help me?
Is any other possible situation to cause lose message?
Is any code I lost and need to check? (EX: iOS part)
Or lost some message is normal, FCM doesn't guarantee to send 100%
Firebase does not guarantee delivery of silent notifications in iOS by using content-available.
As per firebase documentation for content-available,
"Note that silent notifications in APNs are not guaranteed to be delivered, and can depend on factors such as the user turning on Low Power Mode, force quitting the app, etc. On Android, data messages wake the app by default."
Here's a workaround that I think might work for you.
For your iOS device, send a notification payload with mutable_content as true, a dummy notification object and some sort of flag in your data object that indicates this is meant to be a silent notification(something like isSilentNotif=true).
Now write a notificationservice that extends UNNotificationServiceExtension. You will get control in your notification service before the notification is displayed to the user. Here check for the flag you included (isSilentNotif) and hide the notification programmatically if the flag is true and perform the background operation you wanted to perform here.
Lets say I have a chat application and I am messaging another user (User B), our messages are being received normally using sockets, however when the User B goes offline he is disconnected from the socket server however user A is continues to text him so my server issues a push notification to User B's device for every message User A sends. My question is will APNS act as a message broker and queue all the messages until User B logs back in and receives them? Or do I have to store unreceived messages elsewhere
The answer is readily found in Apple's documentation
Apple Push Notification service includes a Quality of Service (QoS) component that performs a store-and-forward function. If APNs attempts to deliver a notification and the destination device is offline, APNs stores the notification for a limited period of time and delivers it when the device becomes available again. This component stores only the most recent notification per device and per app. If a device is offline, sending a notification request targeting that device causes the previous request to be discarded. If a device remains offline for a long time, all its stored notifications in APNs are discarded.
So, no, you can't use APN as a message broker.
You can use the push notification as a signal to wake up and sync with a server-side message queue. RabbitMQ or Kafka might be candidate brokers, and MQTT looks promising as a protocol. You will need to work out how and when you discard the contents of message queues that are not successfully delivered to a device.
Is it possible to send data messages to iOS devices in FCM without using APNs?
I need to send some "live" data to my iOS client app while it is running, instead of polling my servers.
There are 2 reasons I want FCM not to use Apple notifications:
I don't want any kind of system notification/badge/alert to be shown to the user when the app is not running. This is pure app data transfer while the app is running, the rest of the messages can be ignored.
When using Apple notifications the user will be asked the first time if (s)he wants to grant my app notification permissions. If denied my whole app will stop working since the data will not be updated.
I found this post at Firebase Google Groups here where some of the Firebase guys hints that if I don't use iOS specific keys like sound, body, badge, content_available or others:
{
"to" : "<device_id>",
"data" : {
"customKey1" : "value1",
"customKey2" : "value2",
"customKey3" : "value3",
}
}
then they will not use APNs.
All I need is a guarantee of a delivery while my app is in foreground, I wonder if there is a way to configure FCM or messages themselves to reach that goal.
Just a follow up on this. I'm finding that with React Native using this library https://rnfirebase.io/docs/v5.x.x/messaging/receiving-messages i am able to receive data only messages to the iOS simulator (which doesnt support APNS) so looks like data only bypasses APNS.
I'm making a chat with a notification service. Sometimes that the notifications dont arrives to my device. I'm using JavaPNS, so my code isn't very complex, but when I send a lot of messages very quickly (about 10) from one device to another, I don't receive all the notifications. Some of them are lost in the way (generally one of two).
Here is my code:
PushNotificationPayload payload = PushNotificationPayload.complex();
payload.addAlert("Name : text"); payload.addSound("default");
payload.addBadge(1);
payload.addCustomDictionary("type", NOTIF_MESSAGE);
Push.payload(payload, "******.p12", "password", false, URI);
It's OK.
Important: Because delivery is not guaranteed, you should not depend
on the remote-notifications facility for delivering critical data to
an application via the payload. And never include sensitive data in
the payload. You should use it only to notify the user that new data
is available.
-Local and Push Notification Programming Guide.
Apple doesn't guarantee that ALL MESSAGES are ever delivered. The documentation says:
delivery of notifications is “best effort” and is not guaranteed.