5

I'm trying to send a message to a topic with FCM in a Firebase Cloud Function triggered when a Firestore document (a message) is created. Subscribing to the topic (also done with Functions) and triggering the send function works fine, but the actual send fails with:

Error: An error occurred when trying to authenticate to the FCM servers. Make sure the credential used to authenticate this SDK has the proper permissions. See https://firebase.google.com/docs/admin/setup for setup instructions.

and some raw HTML containing <H1>PROJECT_NOT_PERMITTED</H1> and <H1>PROJECT_NOT_PERMITTED</H1> .

Here is my code (index.ts):

import * as admin from 'firebase-admin';

admin.initializeApp({
    credential: admin.credential.applicationDefault(),
});

export * from './messages';

and (messages.ts):

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

export const publishMessage = functions
  .firestore.document('/messages/{messageId}').onCreate(
    (snapshot, context) => {
      const data = snapshot.data();
      const message = {
        notification: {
          title: `${data.sentBy} sent a message`,
          body: data.message,
        },
      };

      return admin.messaging().sendToTopic('messages', message);
    },
  );

According to https://firebase.google.com/docs/cloud-messaging/auth-server#provide-credentials-using-adc this should work. I have also tried doing it without any parameters (https://firebase.google.com/docs/admin/setup#initialize-without-parameters) but it fails all the same. What am I missing?

RJC
  • 1,224
  • 2
  • 12
wujek
  • 10,112
  • 12
  • 52
  • 88
  • Can you confirm that you are using an active `service account`? – RJC Jun 06 '22 at 06:43
  • As far as I know I do. This is a brand new Firebase project and a service account for it is created. When I go to Google Cloud Console to IAM & Admin -> Service Accounts I see two: firebase-adminsdk-xxxxx@.iam.gserviceaccount.com and @appspot.gserviceaccount.com and both are enabled. Neither of them has any keyss but this should not be necessary, right? – wujek Jun 07 '22 at 12:46
  • Yes, it should not matter, what's important is the roles that is included in your `@appspot.gserviceaccount.com`. I've posted an answer to further discuss this. – RJC Jun 08 '22 at 02:39

5 Answers5

3

you can do enable Cloud Messaging API (Legacy) in Project settings/Cloud Messaging

https://i.stack.imgur.com/ElwpB.png

  • Thanks, this will also fix the issue I'm having, although I prefer not to start the project with a legacy FCM setup. See my own answer how to change the code for it work properly. – wujek Jun 26 '22 at 21:10
2

Turns out that instead of this

      const message = {
        notification: {
          title: `${data.sentBy} sent a message`,
          body: data.message,
        },
      };

      return admin.messaging().sendToTopic('messages', message);

I needed this:

      const message = {
        notification: {
          title: `${data.sentBy} sent a message`,
          body: data.message,
        },
        topic: 'messages',
      };

      return admin.messaging().send('messages', message);
wujek
  • 10,112
  • 12
  • 52
  • 88
1

After removing the (roles/firebase.admin) in my <projectId>@appspot.gserviceaccount.com, I also encountered your error:

enter image description here

Since the <projectId>@appspot.gserviceaccount.com service account is being used by Firebase Cloud Functions. Roles and permissions added to this service account carry over to the Cloud Functions runtime.

As you've already stated, you have <projectId>@appspot.gserviceaccount.com, make sure that it has a (roles/firebase.admin), and according to this documentation, it has a full access for cloudmessaging.* permission.

After I re-added the <projectId>@appspot.gserviceaccount.com and the correspoding (roles/firebase.admin):

enter image description here

I've tried adding another Firestore document to test the function (after 10 minutes or so) just to make sure that the changes in my permissions have taken effect:

enter image description here

For other options, you can also try to add the:

  1. Firebase Grow Admin (roles/firebase.growthAdmin);
  2. Or you can try the beta of Firebase Cloud Messaging API Admin (roles/firebasecloudmessaging.admin) since it also has cloudmessaging.* permission.

You can also check the other roles with it's corresponding permissions.

RJC
  • 1,224
  • 2
  • 12
  • I added the role to both accounts and nothing changed. I also don't understand why I would need to do this as I never disabled or deleted anything, I have a fresh Firebase project. – wujek Jun 09 '22 at 00:01
  • I've updated my answer and provided screenshots, and the steps I've done in order to replicate your error and find a solution. – RJC Jun 09 '22 at 01:35
  • I retested it and also waited about 20 minutes (didn't wait in my previous test) but it doesn't change anything, unfortunately. – wujek Jun 09 '22 at 12:30
  • Since my proposed solution didn't resolve your issue, you can file a support ticket directly to [Firebase Support](https://firebase.google.com/support). – RJC Jun 10 '22 at 06:48
1

This is because Google Firebase versions changed and admin.messaging().sendToDevice() no longer works out of the box.

Now following works well:

var admin = require("firebase-admin");
var serviceAccount = require('./xxx.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

const registrationToken = 'fKuD...';

const message = {
  token: registrationToken,
  notification: {
    title: "FCM IS COOL !",
    body: "Notification has been recieved",
    imageUrl: "https://i.ytimg.com/vi/iosNuIdQoy8/maxresdefault.jpg"
  }
}

admin.messaging().send(message);

Note databaseURL in firebase-admin is no longer needed. Just private key you download in Firebase Console.

Jarda Pavlíček
  • 1,636
  • 17
  • 16
1

In my case, enabling API solved the issue. Seems like by default only Firebase Cloud Messaging API is enabled but Cloud Messaging API is not enabled. You need to enable that one from APIs page and it will solve the issue

Elmar
  • 2,235
  • 24
  • 22