React-native-firebase: get push notification when app is closed/killed- Android

Created on 30 Apr 2018  路  50Comments  路  Source: invertase/react-native-firebase

I'm trying to show push notification when app is closed so I'm setting up the push notification as described in docs

I set AndroidManifest.xml
https://pastebin.com/MXRzAhPY

then I wrote the code in react native

`   import React, { Component } from 'react'
import { View } from 'react-native'
import { Input, Text, Button } from '../Components'
import type { RemoteMessage } from 'react-native-firebase'
import firebase from 'react-native-firebase'
import type { Notification, NotificationOpen } from 'react-native-firebase';

export default class TestComponent extends Component {

  async componentDidMount() {
    await this.SetUpAuth();
    await this.SetUpMessaging();
    this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
      // Get the action triggered by the notification being opened
      const action = notificationOpen.action;
      // Get information about the notification that was opened
      const notification: Notification = notificationOpen.notification;
    });
    const notificationOpen: NotificationOpen = await firebase.notifications().getInitialNotification();
    if (notificationOpen) {
      console.log(notificationOpen)
      // App was opened by a notification
      // Get the action triggered by the notification being opened
      const action = notificationOpen.action;
      // Get information about the notification that was opened
      const notification: Notification = notificationOpen.notification;
    }


  }
  componentWillUnmount() {

  }


  async SetUpAuth() {
    const credential = await firebase.auth().signInAnonymouslyAndRetrieveData();
    if (credential) {
      console.log('default app user ->', credential.user.toJSON());
    } else {
      console.error('no credential');
    }
  }
  async SetUpMessaging() {
    this.notification2 = new firebase.notifications.Notification()
      .setNotificationId('notificationId')
      .setTitle('My notification title')
      .setBody('My notification body')
      .android.setChannelId('test')
      .android.setClickAction('action')
      .setData({
        key1: 'value1',
        key2: 'value2',
      });

    this.notification2
      .android.setChannelId('channelId')
      .android.setSmallIcon('ic_launcher');
    console.log('assa')

    onTokenRefreshListener = firebase.messaging().onTokenRefresh(fcmToken => {
      console.log('token generated ->', fcmToken);
      //   store.dispatch(DeviceActions.SetFCMToken(fcmToken));
    });

    const fcmToken = await firebase.messaging().getToken();
    if (fcmToken) {
      // user has a device token
      console.log('has token ->', fcmToken);
      console.log(firebase.auth().currentUser._user)
      firebase.database().ref(`/users/${firebase.auth().currentUser._user.uid}`).set({ pushToken: fcmToken })
      //   store.dispatch(DeviceActions.SetFCMToken(fcmToken));
    } else {
      // user doesn't have a device token yet
      console.error('no messaging token');
    }

    const messagingEnabled = await firebase.messaging().hasPermission();
    if (messagingEnabled) {
      // user has permissions
      console.log('User has FCM permissions');
    } else {
      // user doesn't have permission
      console.log('User does not have FCM permissions');
      await this.RequestMessagePermissions();
    }

    messageListener = firebase.messaging().onMessage((message: RemoteMessage) => {
      console.log(`Recieved message - ${JSON.stringify(message)}`);
    });

    notificationDisplayedListener = firebase
      .notifications()
      .onNotificationDisplayed(notification => {
        // Process your notification as required
        // ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
        console.log(`Recieved notification 1`);
      });
    notificationListener = firebase
      .notifications()
      .onNotification(notification => {
        console.log(notification)
        firebase.notifications().displayNotification(this.notification2)
        // Process your notification as required
        console.log(`Recieved notification 2`);
      });
  }


  async RequestMessagePermissions() {
    console.log('request')
    console.log('Requesting FCM permission');
    await firebase
      .messaging()
      .requestPermission()
      .catch(err => console.err(err));
  }


  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

      </View>
    )
  }

}`

then I created firebase http function just for test
https://pastebin.com/67LV2Gv9
`

in the response from http function I get success(as you can see here)
https://pastebin.com/kFNM3Cbj

but the issue I don't get push notification when app is closed. I want to get any notification when I'm not into the app.
I want the notification to be with any icon or something but I don't see nothing.

Notifications Android Waiting for User Response

Most helpful comment

Does anyone find the solution I am still facing the issue in my case I am receiving notification when the app is in foreground or background but unable to receive when the app is closed or killed Only in android version above oreo for android version below oreo i am receiving notification in all case foreground , background and closed/killed. @chrisbianca need help.

All 50 comments

The second link no longer works - can you just include all the code in the issue please?

When the app is in the background or closed, using the method you're using, you should see the notification in the notification tray on Android - you won't see a heads up notification.

Yes, I edited the code. you can see. I still not get any notification when the app is closed.

Do you have any example that works?

Do you receive the notification when the app is in the foreground?

yes, when I'm on the app I see in react-native debugger it print the notification in console.log that I get notification here

notificationListener = firebase
      .notifications()
      .onNotification(notification => {
        console.log(notification)
        firebase.notifications().displayNotification(this.notification2)
        // Process your notification as required
        console.log(`Recieved notification 2`);
      });

then It run this line
firebase.notifications().displayNotification(this.notification2)
with this notificaiton

` this.notification2 = new firebase.notifications.Notification()
      .setNotificationId('notificationId')
      .setTitle('My notification title')
      .setBody('My notification body')
      .android.setChannelId('test')
      .android.setClickAction('action')
      .setData({
        key1: 'value1',
        key2: 'value2',
      });

`
as you can see setTitle('my notification title') it's hardcoded text I wrote, I want to set details of notification i get in console.log(notification). in addition I want it to work when app is closed

you can see the image on console.log here
https://imgur.com/JXGP8WD

Just to clarify, you want to show a heads up notification when the app is in the background or killed?

I want to show head up notification when the app was just swiped away from the Recents screen, in other words not in background

In which case, you'll need to implement a data-only message as explained here: https://rnfirebase.io/docs/v4.0.x/messaging/receiving-messages#4)-(Optional)(Android-only)-Listen-for-FCM-messages-in-the-background

Then using the data, build up a notification to display.

  • . it works when app is closed? not in background?
  • .I see it works with android only. what can I do in IOS?
  • It works in the background and when the app is closed
  • in iOS the notification part will work as expected

okay. when the app is in background and I get the notification here

notificationListener = firebase
      .notifications()
      .onNotification(notification => {
        console.log(notification)
        firebase.notifications().displayNotification(this.notification2)
        // Process your notification as required
        console.log(`Recieved notification 2`);
      });

as you can see in console.log(notification) I get the notification
https://imgur.com/JXGP8WD
How can I display the notifciation with the details?
if I use this code

` this.notification2 = new firebase.notifications.Notification()
      .setNotificationId('notificationId') 
      .setTitle('My notification title')
      .setBody('My notification body')
      .android.setChannelId('test')
      .android.setClickAction('action')
      .setData({
        key1: 'value1',
        key2: 'value2',
      });`

the setTitle('My notification title') it's hardcoded. I want kind of send the details to this notification instance and display my notification..

These are now implementation questions, rather than an issue - please ask on Stack Overflow or our Discord channel.

Closing.

hi @adirzoari, I have the same problem, any update with this issue?

Same with me

For that you need proper permissions.
https://rnfirebase.io/docs/v4.0.x/messaging/receiving-messages#1)-Check-permissions

This registers with Android.

Now you gotta remember when your app is closed-closed, it isn't running. But, Android is. So basically you need to pack the push with the info Android needs, structure the way Android likes it. Push notification needs a "notification" key set to an object with a body and title. You can still put a message in there and some data, but these now have to be siblings. A POST to https://fcm.googleapis.com/fcm/send would look like this.

{
    "to" : "<token>",

    "notification" : {
      "body" : "This is an FCM notification message!",
      "title" : "FCM Message"
      },
     "message":
        { "body": "",
          "icon": ""
        }
} 

Does anyone find the solution I am still facing the issue in my case I am receiving notification when the app is in foreground or background but unable to receive when the app is closed or killed Only in android version above oreo for android version below oreo i am receiving notification in all case foreground , background and closed/killed. @chrisbianca need help.

Have you rtfm?

https://rnfirebase.io/docs/v5.x.x/messaging/receiving-messages#4)-(Optional)(Android-only)-Listen-for-FCM-messages-in-the-background

everything works fine in android lower than Oreo, i can receive notifications foreground, background even when app is idle (i leave it idle for hours). But when i tested it in Oreo and Pie, i can not receive notifications when i leave the app idle for hours probably because service is kiled automatically, though i still can receive notifications when in foreground and background. The real problem is when i leave the app idle for hours notifications tray did not show its work. Anyone experience the same?

@adirzoari Did you find the solution for your problem?
I am also trying to display a notification with additional details when the app is in the background and killed.

When app is killed, notification is displayed but onNotificationDisplayed is not getting called in Android. Is this expected behaviour?

Please see https://rnfirebase.io/docs/v5.x.x/notifications/receiving-notifications#App-Closed for more information. Your onNotificationDisplayed listener is a JavaScript function which is not running when the app is closed.

Is there some way to call this ? Actually I am using data only notifications, Just showing a heads up notification won't work in my case. I have to do some logic (dispatching redux action which can't be done outside component) also when notification is displayed

It's not always necessary that user will click on that notification when app is in killed state

https://rnfirebase.io/docs/v5.x.x/messaging/receiving-messages#2)-Handle-background-messages

Only available on Android.

@Ehesp I have already implemented this headless task which is why I am receiving messages (data only) even when app is killed/destroyed

But I cannot dispatch redux actions from bgMessaging.js file as it is not a React Component

My flow for notifications is as follows - My server sends me a data only notification,In my onMessage function I do some processing (dispatching redux actions and preparing body for the local notification etc) and then display a local notification using displayNotification

In case when app is in background (not killed) I rely on onNotificationDisplayed method. I display a temporary local notification displaying like Please wait..Fetching data and immediately replace it with actual local notification as soon as the processing inside onNotificationDisplayed is completed

I am able to do this because onNotificationDisplayed is inside React Component class

I am stuck on how to handle the case when app is killed

You can't do that I'm afraid. Remember that the JavaScript side of your app is only running when the app is loaded. For you to access anything JavaScript/app related, the app has to be open/running.

I'm still confused why you need to do this though - you're trying to update redux when the app is killed. Even if this was possible, updating redux has no effect on an killed app.

You should still be able to trigger a notification when the app is killed, just it would be more raw JavaScript you have to execute, not anything which runs directly within your application.

When is app killed, is it really possible to get a notification?
For me Notification is not received, bgMessaging.js i.e, HeadlessJSTask callback is not triggered when app is closed. HeadlessJSTask reallys works in this case?

if you really killed the app (force close), then no. Your app is dead dead. However a FCM data-only / silent-push message might re-open the app depending on vendor (http://dontkillmyapp.com) and/or if you have a boot receiver when the device reboots you'll start up again. Touchy stuff, all of this.

@mikehardy then in same device how other apps send push notification when app is closed?

All the discussions I see in this area suffer from lack of precision, and make it very hard to establish facts.

@gypsicoder what exactly do you mean by closed? Closed how (like, you flicked the app away, or like you went into app info and force stopped it)? What exactly do you mean by push notification? For the purposes of this discussion you'd need to post an example JSON payload like so

 {
      "notification": {
        "body": "Test notification",
        "title": "Test title",
        "sound": "default",
        "click_action": "answer",
        "badge": 0
      }.compact,
      "data": {
        "stuff": "stuff needed to process the action"
      }.compact
    }

What exact device including Android API version? What power settings are in use on the device and is the app pinned or on the secret vendor whitelist (like WhatsApp always is...)

@mikehardy By closed I mean by swiping from recent apps list. And by push notification I meant sending notification form firebase cloud messaging console.

I asked for more :arrow_up: (lack of precision in these discussion is exactly what I'm talking about. Data only push? what device? which app are you comparing to? what versions of everything? has the user disabled battery optimizations? pinned the app?)

@mikehardy I have just used firebase cloud messaging in my project. I checked in my nokia 6 android 7.1.2 (API level 25). When I send notification message from firebase console I get the message if the app is in front or in background. When I close the app from recent app list by swiping, then if I send message from firebase console I don't get that. Is there any way to get notification message or just data message by using FCM if app is closed from recent list?

I'm not satisfied by the 'send notification message from firebase console' statement - it's impossible to say what exact message was sent. When testing these things you should use the API and push a precise message so you have control. An example (you will need your own server key, google docs show how to set them up):

mike@isabela:~/work/Kullki/ksocialscore/packages/public-app (vp1 *) % more publish/test-silent-push.sh 
#!/bin/bash

DEV_SERVER_KEY="My big ugly server key string here"

SERVER_KEY=$DEV_SERVER_KEY

curl -X POST \
--header "Authorization: key=$SERVER_KEY"  \
--Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"/topics/AppInfo\",\"collapse_key\": 
\"AppInfo\",\"content_available\": true, \"priority\": \"high\", \"data\":{\"IconCheck\":\"Testing Icon\"}}"

That is only an example, I'm not sure it serves the purpose of testing your specific case but it what I'd expect in order to troubleshoot with precision - you need to fully control the message payload.

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

https://firebase.google.com/docs/cloud-messaging/android/receive

https://firebase.google.com/docs/cloud-messaging/android/receive#restricted

So, it depends?

@mikehardy I have sent data message successfully from postman by using this url https://fcm.googleapis.com/fcm/send
But the problem is when I close the app by swiping I don't get the notification in tray.

Here is sample payload data which I am sending from postman

{
"to":"dk8-uGoCzDU:APA91bEay0xCnm7GRIjJ5zNmTkONy4gLR04axVvdiLlx-qB3nyQ5kNsHS_zhYbciJe5MljvlzFMfkYOQils31rpeXL_wnX0f5gr-1twzVnvyCsZ8i9Bhm-D0QnVGoBA3buRyUP4zLcXy",
"data": {
"tracking_number": "19007001",
"message": "test data notification 2"
}
}

Getting there, I think. Try suggestions here https://dontkillmyapp.com/nokia

@mikehardy thank you for your effort on trying me to help. But, is there any way for showing notification tray independent of devices?

Not that I'm aware of, until you are are powerful/popular that like WhatsApp you are included in most vendors secret white lists. I have had some success using react-native-background-fetch to wake up the app and do things as a headless task. But it is all generally unreliable. That's the state of mobile.

@mikehardy thank you for giving the reference. I will give a try with that package. But one thing, in one app I have seen that if I send notification through onesignal.postNotification for specific user (with playerID) then the app get notification even if the app is closed. Is it possible by using onesignal?

Anything is possible - I don't mean to be irritating but I am being deliberately vague. It will likely be possible but vary with the devices current power configuration, the history of the user interaction with the app, which mobile vendor and OS version + patch level they are on, and on and on

The theme I'd like to get across is that it is unreliable. Possible? maybe? reliable? never

@mikehardy Yes, I understand. Thank you for helping by giving some valuable information.

plz check my error
https://stackoverflow.com/questions/58097745/how-to-fix-error-no-task-registered-for-key-rnfirebasebackgroundmessage-when-app

i have problem in get fcm message when app close( in foreground and background not problem but in close i have problem... help me plz.)

in manifest
do i need receiver?

@sam9010 Are you testing in device? If in device what's the brand and model? If your device is in the list of here https://dontkillmyapp.com/ then you might not get notification when you close the app.
I haven't found any way to fix that. Maybe we have to do something with background service or something like that to keep the app open in background even if user swipes off the app.

@gypsicoder my phone is samsung note 4
i think no problem from my device
in setting i have problem
did you work react-native-firebase for get fcm?
can you give me your setting an sample
and
must be createChannel in my project for get fcm?
thanks

@sam9010 I just followed sample project of react-native-firebase. Follow that. It would work. Do you have tested in emulator? In emulator you will get push notification if you even close the app. Check that for confirmation they you set it up correctly.

@gypsicoder thanks
i fix it

@sam9010 same problem.... how do you fix it?

@johnsaby you must put
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => firebaseBackgroundMessage); // <-- Add this line
in index, not any where

@sam9010 What's the definition of the function firebaseBackgroundMessage ? Will you please provide an example. When you use this do you get push notification from firebase console if you kill the app by swiping from recent app list?

@gypsicoder after put
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => firebaseBackgroundMessage);
in index
you may define "firebaseBackgroundMessage" function any way
export async function firebaseBackgroundMessage(message: RemoteMessage) { let notif=message['data']; console.log(JSON.stringify(message)); getMessage(notif,message); return Promise.resolve(); }

and so "getMessage" function handel your fcm
for exp. my this function is

function getMessage(notif,message) { if(notif!==null){ let data = JSON.stringify(notif); console.log(data); if (data.includes('FCM_MESSAGE_KEY')) { let Data = notif.FCM_MESSAGE_KEY; Data = JSON.parse(Data); let msg = {}; msg.customerID = Data.customerID; console.log(Data.customerID); } else if (data.includes('SEND_NOTIFICATION_TO_RECEIVER')) { let Data = notif.SEND_NOTIFICATION_TO_RECEIVER; Data = JSON.parse(Data); sendNotification(message,Data); console.log('SEND_NOTIFICATION_TO_RECEIVER!') } else if (data.includes('GCM_MESSAGE_KEY_CUSTOMER_LOGOUT')) { console.log('logout!') } } }

Hi. I remove this line from my manifest and now i can receive notification when app is killed

<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
Was this page helpful?
0 / 5 - 0 ratings