I want to implement push notifications on both Android and iOS with Google Cloud Messaging.
I don't want to use the notification key in my payload because the Android behavior is not ideal. On Android, I would prefer my receiver to always get triggered with the data payload, and I can construct the Notification myself using NotificationCompat. If you use the notification payload on Android, you have no control over the notification style, for example.
However, if I only send a data payload, I think my iOS app will not receive the push if it is backgrounded - killed, never launched since device restart, etc. I think there's that content_available flag for GCM which may trigger the push anyway?
Am I, on iOS, able to duplicate the Android behavior of always having my in-app code execute upon notification? I'd be fine constructing my own iOS notification based on the GCM data payload, and perhaps using something like a UILocalNotification, but from what I'm reading, iOS is requiring the notification payload to exist to make sure the push is always received by the user.
Can I get this kind of control on iOS?
You have to disable the content_available flag to false, so that it works on Ios as expected and provide full control on android,
Source:- I have worked on Push Notification on both android and IOS recently
From my research, it seems that you can't avoid using the notification payload. However, you can get rid of the default Android behavior of auto-creating a notification, if, instead of creating a MyGcmListenerService that extends GcmListenerService, you create your own GcmListenerService and extend plain old Service.
Related
In Firebase push notifications, the payload can be of type "notification" or "payload", but they arrive (or not) depending on whether the app is in background or not and other details. Please clarify them.
(This answer focuses on Android devices)
Firebase Cloud Messaging (FCM) push notifications can be of three types : notification, data and notification+data.
Notification messages are meant to be received by the Android operating system itself, with no intervention by the app. When received by Android, they will be shown as a notification in the tray. Some details:
The tray notification will not be shown if received when your app is in the foreground.
You can implement a FirebaseMessagingService (see the data payload for more info on this), which will receive the message if your app is in the foreground. In your FirebaseMessagingService, you can show a tray notification yourself (or do whatever you want) when you receive the message.
When sending the message, you can specify what happens when the user clicks on the notification; this can be controlled by either specifying an activity in the click_action Android-specific option (see this) or by specifying an URL in the link property and having your app configure an intent filter associated with the URL you specified.
Data messages are meant to be received by an Android service of your app. This service can, in principle (see below [*]), receive the messages when your app is in the foreground, in the background, or not running at all. Some details:
To implement the service, you have to extend FirebaseMessagingService and configure it in your app's manifest.
When you receive the message in your FirebaseMessagingService, you can decide to emit a local notification to be shown in the tray. You can do this either when your app is in the background or in the foreground, in principle (see below [*]). Of course, you may also decide to do other stuff instead (or apart) of showing the tray notification.
[*] Some phone manufacturers, especially Chinese ones like Xiaomi and Oppo, implement some mechanisms to save battery that include killing services. This means that, by default, your FirebaseMessagingService will not be running on those phones unless your app is on the foreground and, therefore, it will NOT receive your data payloads when your app is not on the foreground. There is no way around this, except if the user whitelists your app specifically. The famous apps like Whatapp or Gmail are by default included in the whitelist, but yours won't; therefore, if you rely on data payloads and you want your app to work on that kind of phones, you'd better guide your user to configure their phone to allow it; here you can see how to do it for Xiaomi (Miui) devices. This can also happen in vanilla Android devices since Android 9 (API level 28) with background restrictions, but the behaviour is opposite: your service won't be killed unless the user requests it; you can check this with ActivityManager.isBackgroundRestricted
Notification + data messages include both types of payloads. They behave exactly like notification payload-only messages:
When your app is in background, Android shows the notification in the tray. The data payload is accessible to the app if it receives the intent invocation when the user clicks (described above) in intent.extras.
When your app is in foreground, your FirebaseMessagingService receives the notification with the contents of the data payload.
We have been trying for the last two weeks to get a reliable solution to try and sync our app data with a server in the background. We have tried the Background fetch mechanism but due to the iOS restrictions on when it runs it is not a viable solution.
iOS does provide Remote Notifications (https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app?language=objc) that we would like to use as we can use the same mechanism on Android.
The issues is that when sending a type 2 notification CN1 only delivers the notification when the app is brought to the foreground by the user.
On Android I see there is a Build Hint for android.background_push_handling that allows the notifications to be sent to the app even if it is in the background.
Is there a similar build hint that we can use for iOS?
If not, is there a way then to override the application:didReceiveRemoteNotification:fetchCompletionHandler: method that fires when the Notification arrives so that we can forward it to our app?
You can use silent push notifications for that purpose. To send a silent push notification you just have to include "content-available" : 1" into the body of the notification. More info on that here: Apple docs-silent push notifications
You should bear in mind that this will only work when your app is in the background, it won't work when the app is killed. When the app is killed the only solution is standard push notifications, unless your app has VoIP functionality, in which case you are allowed to use PushKit framework (if you use it in an app without VoIP functionality, you won't get pass the AppStore).
FCM lets us send push messages with two kinds of payload (notification and data), which are handled differently on Android:
notification messages, which contain only notification data
data messages, which contain only custom data
notification+data messages, which behave differently depending on whether the app is in foreground or not
In the third case, if the app is in foreground, the message is handled by a custom FirebaseMessagingService subclass in onMessageReceived(RemoteMessage). Otherwise, the system (or, more precisely, Google Play Services), builds the push notification.
I'd like to build a notification in onMessageReceived(RemoteMessage) that would be identical to the notification that the system would build if the push was received while the app is dead or in background, ie. taking into account the notification data received in the push (RemoteMessage.Notification), the defaults set in the Manifest's meta-data, etc. Is there a method in the SDK that would allow that, or maybe a third-party library, or do I have to reverse-engineer it by myself?
I'm currently implementing a Chat application using Firebase Cloud Messaging to send push notifications. Using the notification field in the API call, Firebase displays them automatically without having to manually create a service and listen for the messages.
The push notification is pretty generic, just says "You have a new message!", so it doesn't make sense to keep adding new pushes every new message, I need firebase to not show a new push if the message body contents the same of a previous one.
Is it posible to do without implementing the service and handling Notification show manually? Found no references of this use case in the documentation.
If your application is in Foreground then you receive the notification in onReceive of your FirebaseMessagingService. Else notification is delivered to system notification tray. Since you don't know the id of the notification so you may not retrieve it. It is also possible that your application is not running at the time you receive the notification. So logically it is NOT possible even by implementing the service. Well you can solve the problem by another approach. You can use Firebase Database in conjuction with Cloud Functions. Just have a look on developer guide of cloud functions and you will find that they can help yourself achieve you what you want. As a solution skeleton : Post messages to Firebase Database and Send notification using cloud functions. When the recipient reads the message update the database to reflect message has been read like having a variable seen. Design your cloud function such that it reads the value of seen value of last message and sends notification only if it was true. Hope this helps.
For manual handling you have to use the service. Go for handleIntent(intent) of FirebaseMessagingService.
This method gets called when application is in foreground, background and killed state. To avoid the duplication, do not call super.handleIntent(intent). This will prevent the automatic push notification when app in BG or killed state.
This worked for me.
I'm using Parse to send push messages to my app. In some cases I want to show a notification however in some cases I don't. For example when data should be updated I intend to send a notification to all devices so that way they don't have to poll. This should not show any notification.
Parse's GcmBroadcastReceiver seems to always generate a notification without any way of turning that off.
I'm also curious of how to stop Parse from auto-creating a notification because at some point I'm going to want to work with more complex notifications, which Parse doesn't support.
I've tried creating my own GcmBroadcastReceiver however when I did that I didn't receive anything. Maybe I rigged it wrong? Other than that how can I stop Parse SDK from auto-generating a notification?
Omit alert and title from your push notification and the parse.com android SDK will not create a notification.