4

I have an android app that successfully receives notifications from the Firebase console. I now intend to build a nodejs server where we can send these notifications to save logging into the firebase console, however, it appears that the node.js library 'firebase-admin' only supports sending to individual device ids or topics rather than all devices as per the console.

So I've made a nodejs service to send to topic 'all', and tried to alter android to receive these notifications, however I get no notifications on my device from this nodejs server.

Here is my server code:

var admin = require("firebase-admin");

var serviceAccount = require("./firebase-privatekey.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://myapp-android-xxx.firebaseio.com"
});

var payload = {
    notification: {
        title: "Account Deposit",
        body: "A deposit to your savings account has just cleared."
    },
    data: {
        account: "Savings",
        balance: "$3020.25"
    },
    topic: "all",
};

admin.messaging().send(payload)
    .then(function(response) {
        console.log("Successfully sent message:", response);
    })
    .catch(function(error) {
        console.log("Error sending message:", error);
    });

This is the android code that worked with the console notifications:

public class MyNotificationService extends FirebaseMessagingService {
    public MyNotificationService() {
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d("Firebase", "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d("Firebase", "Message data payload: " + remoteMessage.getData());
            handleNow(remoteMessage.getData(), remoteMessage.getNotification().getBody());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d("Firebase", "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }
    }

    public void handleNow(Map<String, String> data, String title) {
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);

        int notificationId = 1;
        String channelId = "channel-01";
        String channelName = "Channel Name";
        int importance = NotificationManager.IMPORTANCE_HIGH;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(
                    channelId, channelName, importance);
            notificationManager.createNotificationChannel(mChannel);
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(), channelId)
                .setSmallIcon(R.drawable.myapp_notification_icon)
                .setBadgeIconType(R.drawable.myapp_notification_icon)
                .setContentTitle(title)
                .setContentText(data.get("information"));


        notificationManager.notify(notificationId, mBuilder.build());
    }
}

and this is the new (Additional not replaced) code, with the intention of receiving topic messages:

@Override
protected void onCreate(Bundle savedInstanceState) {
    //other code...
        FirebaseMessaging.getInstance().subscribeToTopic("all")
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()) {
                            System.out.println("win");
                        } else {
                            System.out.println("fail");
                        }
                    }
                });

}

The nodejs server tells me it was a successful send of a message, yet a breakpoint on either the win or fail message never gets hit on android

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Wayneio
  • 3,466
  • 7
  • 42
  • 73
  • 1
    If you are interested, I have exaplained in one of my tutorials step by step, how you can send **[notifications](https://www.youtube.com/watch?v=6RzB4HXzQyA&t=3s&list=PLn2n4GESV0AmXOWOam729bC47v0d0Ohee&index=17)** to specific users using `Cloud Firestore` and `Node.js`. – Alex Mamo Aug 24 '18 at 12:26

1 Answers1

1

I had quite the same problem. The solution I found was adding:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

to AndroidManifest.xml and:

@Override
public void onDeletedMessages() {
    super.onDeletedMessages();
}

to MyFirebaseMessagingService.

According to the docs.

Override onDeletedMessages

In some situations, FCM may not deliver a message. This occurs when there are too many messages (>100) pending for your app on a particular device at the time it connects or if the device hasn't connected to FCM in more than one month. In these cases, you may receive a callback to FirebaseMessagingService.onDeletedMessages() When the app instance receives this callback, it should perform a full sync with your app server. If you haven't sent a message to the app on that device within the last 4 weeks, FCM won't call onDeletedMessages().

grrigore
  • 1,050
  • 1
  • 21
  • 39