React-native-firebase: Android Heads up Notification ( Notification Channel )

Created on 28 Oct 2019  路  30Comments  路  Source: invertase/react-native-firebase

I am using RNF v6 and all notifications are sent from Firebase Cloud functions. Its all good and notifications are received on Android, but i would need to get heads up notifications working on Android. From what i understand, i need to setup notification channel in AndroidManifest.xml for that. I have followed the docs and added this:

 <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id"/>

Build is now throwing error. My guess is that since Notifications are not included as package in V6, perhaps the default channel is not there ?
I realy dont need to create my own channel or anything, just heads up notification on Android even if it means temporarily hacking it, so that i can get the notifications showing up properly on Android until V6 Notifications come out.
Or if there is some other way to set notification priority to max with RNF V6.

Thanks for any suggestions


Android

Platfrom: Android
RN: 0.61.2
RNF: 6.0.0

Most helpful comment

@mikehardy Ok, so that was actually the issue :) It is supposed to be onCreate and not OnCreate 馃うSo that was kinda stupid mistake, but its finaly working, i am getting vibrations and notifications are heads up, so thanks a lot. I would not put it together otherwise.

So if anyone else would need to do the same thing, here is the summary:

In MainActivity.java add this

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

There is no need to setup anything in AndroidManifest, i deleted the metadata for notification channel and its working.

And in Firebase Cloud Function:

var payload = {
     notification: {
           title: "Title",
           body: "Body",
            android_channel_id: "500" 
      }
}

All 30 comments

If you're okay with temp hacking you'd want to create the notification channel in Java during startup (since RNFBv6 has no support for it)

Here's a separate project where I do that, as an example. Note the API skew in that you can't do it on lower APIs so you have to test for android version and only do it on 26 and higher https://github.com/ankidroid/Anki-Android/blob/master/AnkiDroid/src/main/java/com/ichi2/compat/CompatV26.java#L25

For API26 and lower you just skip it: https://github.com/ankidroid/Anki-Android/blob/master/AnkiDroid/src/main/java/com/ichi2/compat/CompatV15.java#L152

For completeness so you can see the APIs in use this is where that project decides who gets which package of logic: https://github.com/ankidroid/Anki-Android/blob/master/AnkiDroid/src/main/java/com/ichi2/compat/CompatHelper.java#L31

@mikehardy Thanks, i will have a closer look at it, but it seems like its way above my skills in native android.

Btw is there any chance something like this could help ?
Using Cloud function to send notificaiton

admin.messaging().sendToDevice(registrationToken, payload, { priority: "high" })

I did test and it didnt do anything, so i guess not. I would just prefer one line solution to that whole native java hack hehe

I dunno - that was a pretty highly engineered project, but the one-liner is in MainApplication really just doing (in pseudecode) if android version is higher than oreo, create a notification channel named this, and all the actual symbols you need are the reason I sent all the other links. For formatting prettiness I'd probably do it in 3 lines, but I think you can do it :-). I haven't tried doing anything about notifications in v6 though so maybe I'm wrong?

@LukePenkava just add this in onCreate method of MyApplication.java class and fill out empty strings with your values. First argument (string) of the new NotificationChannel( call must be the same as the channel-id which is set on firebase and your backend service which sends the message.

```// Add functionality for heads up notifications
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("", "", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setShowBadge(true);
notificationChannel.setDescription("");
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
notificationChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(notificationChannel);
}

Also you can delete this.
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id"/>

```

@kneza23 @mikehardy Thanks, i actualy found out it was phone settings :) i just wanted to have notifications show up on locked screen as tabs and Samsung has it by default off. I am guessing that users on Android by default dont have notifications shown by as iOS users on locked screen.

@kneza23 @mikehardy Thanks, i actualy found out it was phone settings :) i just wanted to have notifications show up on locked screen as tabs and Samsung has it by default off. I am guessing that users on Android by default dont have notifications shown by as iOS users on locked screen.

I think that manual solution won't work as it wont be enabled on default every time you install the app.

@kneza23 So you mean i can actualy force it eventho user has it in his settings to not show up on locked screen as tab/heads up notification ?

@LukePenkava he can turn it off, but it would be enabled by default.

@kneza23 Great, thank you. I will give a go to your solution then.

@kneza23 I know it should be probably easy, but i was not able to find anywhere how to setup notification channel in firebase console or how to set it with cloud function with

admin.messaging().sendToDevice(notificationToken, payload);

I was able to find only some deprecated way and to set notification channel through AndroidManifest.xml. Could you please point me in some direction how to set it up ( notification channel in firebase console and in cloud function ), just some link would be enough.

I believe the second parameter in the

new NotificationChannel("", "", NotificationManager.IMPORTANCE_HIGH);

is channel name. Can it be anything ?

Thanks a lot
Luke

It's really worth it to read the docs here https://developer.android.com/training/notify-user/channels#java

@kneza23 @mikehardy

So after some research how to put it together i did the following:

In MainActivity.java i added this

  protected void OnCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

In Firebase Cloud function i have added channel id like this:

var payload = {
    notification: {
        title: "Title",
        body: "Body,
         android_channel_id: '500'
  }
 }

admin.messaging().sendToDevice(notificationToken, payload);

But its unfortunately still not working :( Any help appreciated. Thanks

Interesting. Appears FCM sets up a default that should work? And you can manage it in the AndroidManifest https://firebase.google.com/docs/cloud-messaging/android/client#manifest

You could try setting your android channel id (500) in the manifest like that to see if it is working? Regardless, you should open up an unfiltered adb logcat against the test device to see what it says when the notification hits it. If it's a channel issue it should fail delivery and throw an error with details in logcat

@mikehardy @kneza23 I think have set it up quite wrong i think as i just found out i should put the native java code into custom appname.java file. So i did that and i am currently stuck on getsystemservice error. If there are any other issues you can see, let me please know.
This whole native to react native code is completely new for me, so i have realy no idea what i am doing.

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestNotifications implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>(); 
    return modules;
  }


  public void OnCreate(Bundle savedInstanceState) {
      /*super.onCreate(savedInstanceState);*/

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
              NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
              notificationChannel.setShowBadge(true);
              notificationChannel.setDescription("Test Notifications");
              notificationChannel.enableVibration(true);
              notificationChannel.enableLights(true);
              notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
              //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
              NotificationManager manager = getSystemService(NotificationManager.class);
              manager.createNotificationChannel(notificationChannel);
          }
  }
}

I actually thought it was fine in your onCreate on the main activity? And you should have been able to see (in app preferences on device) the new channel to confirm it worked.

@mikehardy thats why i went to this, because i actualy didnt see the new channel in the app settings on the device with the code in MainActivity.java :/

Instead of moving it around, I'd put System.err.println('whatever you want here'); statements around the execution and watch logcat. Just to prove it is executing. I'd put them at the start and end of the method as well to make sure the whole onCreate is executing. I suspect logcat will have something else interesting to say. Maybe the device is less than Android 8 so it's a no-op? :thinking:

@mikehardy So i did check the logcat ( after reverting back to the code in MainActivity.java ) and was able to find this, which is hopefully the problem:

2019-11-11 23:52:44.916 27395-29325/com.test W/FirebaseMessaging: Notification Channel requested (500) has not been created by the app. Manifest configuration, or default, value will be used.
2019-11-11 23:52:44.919 27395-29325/com.test W/FirebaseMessaging: Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
2019-11-11 23:52:45.119 4313-4313/? I/AccessibilityManager: semStartFlashNotification notitype = null

I am guessing i should setup the notification channel with 500 in AndroidManifest ?

Edit: I am realy not sure what to put into the AndroidManifest.xml. I tried few variations like this with no luck, still same error:

<meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="500"/>

<meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="MainChannel"/>

The creation is still not happening for some reason

Notification Channel requested (500) has not been created by the app

put those System.err.println's in there at all areas near / aroun dstartup creation to make sure it's executing and creating your channel.

@mikehardy So i did this ( as well with System.err.println ) and i could not find any of those logs when in verbose and search directly for those logs:

protected void OnCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    System.out.println("In On Create 1");

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       System.out.println("In On Create 2");
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
            System.out.println("In On Create 3");
        }

      System.out.println("In On Create 4");
  }

So unless i did it wrong ( logging ) it means the onCreate is not getting called at all.

the logging looks correct. it is possible you miss the logs if your logcat is filtered at all. I usually prefix all my logs with something unique for searching like so all messages would be "NOTIFICATION_TEST: " as the string. Just to make sure.

So if that code is not running I'm not sure why. Perhaps it is because it is 'OnCreate' instead of 'onCreate'. mixed casing

@mikehardy Ok, so that was actually the issue :) It is supposed to be onCreate and not OnCreate 馃うSo that was kinda stupid mistake, but its finaly working, i am getting vibrations and notifications are heads up, so thanks a lot. I would not put it together otherwise.

So if anyone else would need to do the same thing, here is the summary:

In MainActivity.java add this

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

There is no need to setup anything in AndroidManifest, i deleted the metadata for notification channel and its working.

And in Firebase Cloud Function:

var payload = {
     notification: {
           title: "Title",
           body: "Body",
            android_channel_id: "500" 
      }
}

I love it when things work! Cheers

@mikehardy Ok, so that was actually the issue :) It is supposed to be onCreate and not OnCreate 馃うSo that was kinda stupid mistake, but its finaly working, i am getting vibrations and notifications are heads up, so thanks a lot. I would not put it together otherwise.

So if anyone else would need to do the same thing, here is the summary:

In MainActivity.java add this

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

There is no need to setup anything in AndroidManifest, i deleted the metadata for notification channel and its working.

And in Firebase Cloud Function:

var payload = {
     notification: {
           title: "Title",
           body: "Body",
            android_channel_id: "500" 
      }
}

can you please also share androidManifest.xml code?

android_channel_id: "500"

I tried above steps it didn't work for me.

i am using react-native :- v0.62 & react-native-firebase :- v5.6.0. @mikehardy

@mikehardy Thanks for the great work on this project.

Headsup works for me on Android versions >=8 (using the notification channel as above). On a Samsung device on Android 7, I get the notification in the tray, but it doesn't give me a headsup display. Supposedly if I send the messages as high priority with a sound, it should give a headsup, but it doesn't. Has anyone tested on < Android 8?

This is how I am sending messages:

     payload = {
        "notification": {
          "title": title,
          "body": body,
          "sound": "default",
          android_channel_id: "notification-channel"
        },
      };
     firebaseApp.messaging().sendToDevice(device.token, payload, {priority: "high"});


(I could switch to data messages and do my own notifications, but then I need another library...)

@mcorner I was facing the same issue. Just figured it out.

      const message = {
        notification: {
          title: data.subject,
          body: data.message
        },
        data: {
          id: data.id,
          title: data.subject,
          body: data.message,
          origin: 'chat'
        },
        android: {
          priority: 'high',
          notification: {
            title: data.subject,
            body: data.message,
            sound: 'default',
            priority: 'high',
            channelId: 'YOUR_CHANNEL_ID'
          }
        },
        tokens: arrTokens
      };

For me, what was missing was the android specific configuration.
Note that I'm using the node.JS version of the firebase messaging so you may have to look for your specific notification android configuration.

@mikehardy Ok, so that was actually the issue :) It is supposed to be onCreate and not OnCreate 馃うSo that was kinda stupid mistake, but its finaly working, i am getting vibrations and notifications are heads up, so thanks a lot. I would not put it together otherwise.

So if anyone else would need to do the same thing, here is the summary:

In MainActivity.java add this

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

There is no need to setup anything in AndroidManifest, i deleted the metadata for notification channel and its working.

And in Firebase Cloud Function:

var payload = {
     notification: {
           title: "Title",
           body: "Body",
            android_channel_id: "500" 
      }
}

this solution worked for me .im working on about 13 hours without any eat and drink and the file not MainActivity.java ,its need to be MainApplication.java , I'm understand this fcm react native lib is not register channel by self.

Thank you @LukePenkava .Have a nice programming days for all.

@emrecanozkok take a break for a good meal! Even if you eat it quickly. :brain: only runs on blood sugar!

@mikehardy Ok, so that was actually the issue :) It is supposed to be onCreate and not OnCreate 馃うSo that was kinda stupid mistake, but its finaly working, i am getting vibrations and notifications are heads up, so thanks a lot. I would not put it together otherwise.

So if anyone else would need to do the same thing, here is the summary:

In MainActivity.java add this

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    
            NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setShowBadge(true);
            notificationChannel.setDescription("Test Notifications");
            notificationChannel.enableVibration(true);
            notificationChannel.enableLights(true);
            notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
            //notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
  }

There is no need to setup anything in AndroidManifest, i deleted the metadata for notification channel and its working.

And in Firebase Cloud Function:

var payload = {
     notification: {
           title: "Title",
           body: "Body",
            android_channel_id: "500" 
      }
}

THANK YOU!!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

neverlan picture neverlan  路  47Comments

adirzoari picture adirzoari  路  50Comments

tranty9597 picture tranty9597  路  79Comments

TalEliel picture TalEliel  路  48Comments

umang-simform picture umang-simform  路  77Comments