22

We are using firebase cloud messaging to get the push notification into android app.

Currently to test push notification we need to send the message to FCM server and wait for the message to arrive to device. Most of the time device is taking long time get the notification from FCM server.

I can see some links below which explains sending push notification to device using adb broadcast command (This example explains sending message using GCM framework, but we use FCM) Is it possible to simulate a GCM receive from the adb shell / am command line? I'm getting an error

Is there any similar way to send push notification using adb to device which have FCM?

LundinCast
  • 9,412
  • 4
  • 36
  • 48
yottabrain
  • 2,387
  • 5
  • 23
  • 37

4 Answers4

11

It is possible to send FCM payloads via adb.

while it is true that the permission com.google.android.c2dm.permission.SEND is a problem, there's a workaround.

gradle adds the FirebaseInstanceIdReceiver to the merged manifest. the workaround is to add your own copy to the manifest and override the permission using the tools:replace="android:permission" and android:permission="@null"

<receiver
        android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
        android:exported="true"
        android:permission="@null"
        tools:replace="android:permission">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="your.package.name" />
        </intent-filter>
</receiver>

then issue

adb shell "am broadcast -n your.package.name/com.google.firebase.iid.FirebaseInstanceIdReceiver -c your.package.name -a com.google.android.c2dm.intent.RECEIVE ... via the terminal

(PS - I highly recommend doing it only in debug builds either via gradle's manifest placeholder or a seperate AndroidManifest.xml in your debug/develop builds)

steineron
  • 389
  • 3
  • 6
  • 1
    In case anyone is facing an issue with this setup when running `aapt dump badging` (`ERROR getting 'android:permission' attribute for receiver 'com.google.firebase.iid.FirebaseInstanceIdReceiver': attribute is not a string value`). I was able to resolve it by removing the lines `android:permission="@null"` and putting `tools:replace="android:permission"` and `tools:ignore="ExportedReceiver"` in their place. – jsa Jul 23 '21 at 12:52
9

It worked for me on the emulator (you need neither server key nor client token).

Run these commands on the AS terminal:

  • adb root -> In order to get the com.google.android.c2dm.intent.RECEIVE permission

  • adb shell am broadcast \
      -n <YOUR.APP.PACKAGE>/com.google.firebase.iid.FirebaseInstanceIdReceiver \
      -a "com.google.android.c2dm.intent.RECEIVE" \
      --es "title" "Title" \
      --es "body" "Body"```
    

where the --es fields correspond with the fields within data node:

{
  "data": {
    "title": "Title",
    "body": "Body"
  },
  "to" : ""
}
ZoFreX
  • 8,812
  • 5
  • 31
  • 51
Miguel Garcia
  • 1,389
  • 16
  • 16
  • My phone does not allow to enable root "adbd cannot run as root in production builds" so I tried running the command as `adb shell "su "` as per other stack overflow answers, even tried the old method of using a broadcast receiver command with the FirebaseInstanceIdReceiver, all to no avail... Do you have any other tips? – bamboo10 Jun 06 '19 at 13:27
  • @bamboo10 I only can think about using it with the FCM user token: - https://console.firebase.google.com > Cloud messaging > New notification - Build the request by hand (you could use Postman, Curl, ..): - URL: https://fcm.googleapis.com/fcm/send - Method: POST - Header params: `Content-Type: application/json` and `Authorization: key={server key}` - Body: {"data":{"title":"Title","body":"Body"},"to":"{user token}"} – Miguel Garcia Jun 27 '19 at 09:36
  • Running `adb root` was the key for me! – Devansh Maurya Jan 11 '22 at 04:10
3

This worked for me on emulator: Simply paste this in your Android studio Terminal :

  adb shell am broadcast -a com.google.android.c2dm.intent.RECEIVE -n MyCOM.MyCOMPANY.MyAPP/com.google.firebase.iid.FirebaseInstanceIdReceiver --es "title" "Congradulation", --es "message" "this is your message", --es "isThisWorking" "yes"

replace the the MyCOM.MyCOMPANY.MyAPP bit with your app package name

bastami82
  • 5,955
  • 7
  • 33
  • 44
1

It's not possible to send push notification from adb command. So your process need following permission to send broadcast through adb. But google doesn't allowed to set com.google.android.c2dm.permission.SEND permission.

If you run below command and try to grant send permission to your package.
./adb shell pm grant com.example.hunted "com.google.android.c2dm.permission.SEND"

You will get following exception

Operation not allowed: java.lang.SecurityException: Package com.example.hunted has not requested permission com.google.android.c2dm.permission.SEND

and even if you add this permission to your package

./adb shell pm grant  com.example.hunted com.google.android.c2dm.permission.SEND
Operation not allowed: java.lang.SecurityException: Permission com.google.android.c2dm.permission.SEND is not a changeable permission type.

At last when you send broadcast using adb. you will get following exception.

BroadcastQueue: Permission Denial: broadcasting Intent { flg=0x400010 cmp=com.example.hunted/com.google.firebase.iid.FirebaseInstanceIdReceiver (has extras) } from null (pid=32279, uid=2000) requires com.google.android.c2dm.permission.SEND due to receiver com.example.hunted/com.google.firebase.iid.FirebaseInstanceIdReceiver
A Farmanbar
  • 4,381
  • 5
  • 24
  • 42
Rajesh Garg
  • 371
  • 3
  • 3