capacitor-community / fcm

Enable Firebase Cloud Messaging for Capacitor apps
https://capacitor.ionicframework.com/docs/
MIT License
238 stars 83 forks source link

FCM push notifications for Android not working direct to token #124

Closed madmacc closed 1 year ago

madmacc commented 1 year ago

Describe the bug After upgrading to Capacitor 3 it appears that sending a push notification direct to a token does not work for Android. The error below occurs in a normal local build or via the Play Store. I get the error:

Unhandled error { Error: The registration token is not a valid FCM registration token
    at FirebaseMessagingError.FirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:44:28)
    at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:90:28)
    at new FirebaseMessagingError (/workspace/node_modules/firebase-admin/lib/utils/error.js:256:16)
    at Function.FirebaseMessagingError.fromServerError (/workspace/node_modules/firebase-admin/lib/utils/error.js:289:16)
    at Object.createFirebaseError (/workspace/node_modules/firebase-admin/lib/messaging/messaging-errors-internal.js:35:47)
    at /workspace/node_modules/firebase-admin/lib/messaging/messaging-api-request-internal.js:79:51
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errorInfo:
   { code: 'messaging/invalid-argument',
     message:
      'The registration token is not a valid FCM registration token' },
  codePrefix: 'messaging' } 

I realize this is normally due to an invalid token e.g. using a dev config or expired token but send push notifications to topics works. These used to work and now do not. I can't pinpoint exactly when they stopped working. I am using Capacitor 3 and upgraded from Capacitor 2 recently.

"@capacitor-community/fcm": "^2.0.2", "@capacitor/push-notifications": "^1.0.9"

This is the error I get:

Unhandled error { Error: The registration token is not a valid FCM registration token
    at FirebaseMessagingError.FirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:44:28)
    at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:90:28)
    at new FirebaseMessagingError (/workspace/node_modules/firebase-admin/lib/utils/error.js:256:16)
    at Function.FirebaseMessagingError.fromServerError (/workspace/node_modules/firebase-admin/lib/utils/error.js:289:16)
    at Object.createFirebaseError (/workspace/node_modules/firebase-admin/lib/messaging/messaging-errors-internal.js:35:47)
    at /workspace/node_modules/firebase-admin/lib/messaging/messaging-api-request-internal.js:79:51
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errorInfo:
   { code: 'messaging/invalid-argument',
     message:
      'The registration token is not a valid FCM registration token' },
  codePrefix: 'messaging' } 

Things I have tested:

  1. Tried a message to the topic from the cloud function. Works.
  2. Tried a message to the token from the cloud function. Did not work. See error above.
  3. Tried a message to the topic from the FCM console. Worked.
  4. Tried a message to the token from the FCM console. Did not work.
  5. Checked the google-service.json file against a latest version from the firebase project. Looks fine,
  6. Testing on iOS topic and token. Works fine.
  7. In Play store Setup -> App Integrity the "Upload Key Certificate" SHA-256 matches the Firebase project for the app. But the "App Signing Key Certificate" SHA-256 does not match. Is this an issue? qiHDu

Cloud function code:

    const notification: admin.messaging.Notification = {
          title: title,
          body: body
      }

      const message: admin.messaging.Message = {
        notification,
        token,
        android:{
          notification:{
            sound: 'default',
            icon: 'push_logo',
            color: '#000000',
          }
        },
        apns:{
            payload:{
              aps: {
                sound: 'default'
              }
            }
        }
      }

      return admin.messaging().send(message)

Which creates:

{ notification: { title: 'test', body: 'test' },
  token:
   'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6IjE6MTAxMzMxMzU1NjY5NDphbmRyb2lkOmQyODI0NGY1MWIzYTkyYTMwN2Y5NzciLCJleHAiOjE2NTk3NTExNTAsImZpZCI6ImV3YkF0c1psUm5xZ2Mzb0tQRWs0VnYiLCJwcm9qZWN0TnVtYmVyIjoxMDEzMzEzNTU2Njk0fQ.AB2LPV8wRQIgbdIAgIU76ziJc84g5gcNFNzFyid2xeDTcAywjecKFKoCIQD1KkflpXmfOSvp28XVmTtm4JtWaaVcycQRMXtKSNUM0Q',
  android:
   { notification: { sound: 'default', icon: 'push_logo', color: '#000000' } },
  apns: { payload: { aps: [Object] } } } 

Ionic (Angular) app code:

     PushNotifications.requestPermissions().then((permission) => {
          if (permission.receive === 'granted') {
            PushNotifications.register().then(result => {
              this.subscribeToTopic(tenant.id);
              // Register for some topics here. Code removed.
              this.saveFCMToken();
            })
            .catch(err => {
              console.log('Push register error');
              console.log(err)
            });

     private async saveFCMToken() {
        try {
          const result = await FCM.getToken();
          const member = this.authService.getCurrentMember();
          if (member) {
            // Save the token against the member
            await this.authService.updateMember(member.id, { fcmToken: result.token });
          }
        } catch(err) {
          console.log('Error saving FCM token')
          console.log(err)
        }
      }

Expected behavior I expect the push notification to work on Android.

Additional context "@capacitor-community/fcm": "^2.0.2", "@capacitor/push-notifications": "^1.0.9"

UPDATE I have found the problem although I have no idea why this happens. On Android if I use

import { FCM } from "@capacitor-community/fcm";
const result = await FCM.getToken();

it returns a token that DOES NOT WORK and looks like this: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6IjE6MTAxMzMxMzU1NjY5NDphbmRyb2lkOmQyODI0NGY1MWIzYTkyYTMwN2Y5NzciLCJleHAiOjE2NjM2NDI0NDIsImZpZCI6ImNhNk94R2lFU0dXYVk1RGU1UTBNTWIiLCJwcm9qZWN0TnVtYmVyIjoxMDEzMzEzNTU2Njk0fQ.AB2LPV8wRgIhAO4---Dns2vDbIdOZsamrVJ4TtEQhPK3qktfX-Q305E3AiEAo7DoZmfKha0LhDPy2QjQrbJBXyfopTnk5AgdZUsik3k

However if I use

import {  PushNotifications, Token } from "@capacitor/push-notifications";
PushNotifications.addListener('registration', (token: Token) => {
      console.log('token.value', token.value)
    });

it returns a token THAT WORKS and looks like: ca6OxGiESGWaY5De5Q0MMb:APA91bFxBvkS_qlMo0DW9F9nVeRsffM5Llms2DZKeq_SfGJBFSyN63LjBQh_CYW7qpFQeTJnjJmDOW1eaIiOH0GTZbxktWkfj_IYrrtdwzwbGVidOEbn67KR7508Uf0kFJKg6vlVeTey

On iOS await FCM.getToken() works fine.

madmacc commented 1 year ago

Ah man. I spent days on this. https://github.com/capacitor-community/fcm/issues/99

How about putting it in the documentation somewhere!