Firebase Messaging v1 401 Project Not Permitted error
Asked Answered
K

4

25

I am running a node server with the firebase admin sdk. However, everytime I try to send a push notification from the server, I get a 401 error.

Here's the exact error I'm getting:

  errorInfo: {
code: 'messaging/authentication-error',
message: '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. Raw server response: "<HTML>\n' +
  '<HEAD>\n' +
  '<TITLE>PROJECT_NOT_PERMITTED</TITLE>\n' +
  '</HEAD>\n' +
  '<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n' +
  '<H1>PROJECT_NOT_PERMITTED</H1>\n' +
  '<H2>Error 401</H2>\n' +
  '</BODY>\n' +
  '</HTML>\n' +
  '". Status code: 401.'
},
codePrefix: 'messaging'

I'm not exactly sure why I don't have permissions to the project. I have setup my service account, and downloaded the .json file. I even went into the gcloud platform and tried to add any permission that looked correct. Below are all the permissions associated with my service account:

permissions

I am running the server locally, and initialized the app like this:

const admin = require('firebase-admin');
const messaging = require('firebase-admin/messaging');
const serviceAccount = require('<path-to-key>');

const fbApp = admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    projectId: '<PROJECT_ID>',
    databaseURL: '<DB_URL>'
});

I am not sure what else to do as I've looked through the v1 documentation multiple times and still don't have any clue as to what permissions I'm lacking. I even made sure to "firebase login" into the correct google account to see if that could've been an issue.

Here's my code to send a message:

const sendPushNotifications2 = async (topic, reminder) => {
    const payload = genPayload2(reminder);
    //await messaging.getMessaging(fbApp).sendToTopic(topic, payload);
    await admin.messaging(fbApp).sendToTopic(topic, payload);
};

I have verified the client_id, client_email, and private_key_id values in the .json file. I haven't yet verified the private_key property because I'm not sure where to find it.

Kenton answered 2/6, 2022 at 17:26 Comment(0)
K
51

The problem is that new Firebase projects have only the new "Firebase Cloud Messaging API (V1)" enabled by default, and with that configuration - the official firebase-admin NodeJS library - that uses the new V1 API - will not be able to send messages and will get 401 PROJECT_NOT_PERMITTED errors.

To be able to send message from your server, you MUST also enable the older "legacy" API.

  1. From your Firebase console, go to Project Settings and open the Cloud Messaging tab.
  2. Make sure that both APIs listed are enabled - see screenshot of how it should look: enter image description here
  3. If any API is not enabled, for the API that is disabled click the three dots menu on the right and select "Manage API"
  4. In the Google Cloud Console page that opens, click the "Enable" button.

Note:

  • This is basically the same answer as @Tial's self answer, but I was confused by it and (as commented) it got some things wrong - it took me a while to understand it (and the linked answer) to get it right, so I had to clarify.
  • As of this writing this issue impacts all uses of the Cloud Messaging APIs, regardless if you use the new (V1) or the lagacy API. I expect Google to fix this at some point.
Kiri answered 8/9, 2022 at 9:18 Comment(5)
Is this still the case, even with the legacy version getting phased out?Cluster
I have not checked recently, but as of the beginning of this year (when the legacy API has been notably deprecated in the UI and disabled by default - for a couple of years now) - this was still the case.Kiri
In that case, is there an easy way to confirm that I'm using v1 functions with a service account and not legacy functions with an API key?Cluster
@MichaelPlischke - yes, it is easy: do not provide the API key to the applications.Kiri
You don't need the deprecated legacy API for topic messaging. Just use the same getMessaging().sendMessage(message)-Function as for other messages and add a topic key to the message as described in https://mcmap.net/q/523341/-firebase-messaging-v1-401-project-not-permitted-errorHinman
K
35

It turns out that I had this API disabled: "Firebase In-App Messaging API" It also turns out that this question was asked before, but I wasn't able to find it. Here's the answer

If anyone else runs into this issue this was my fix:

  1. go to the google cloud platform website
  2. go to APIs and Services
  3. go to Enabled APIs & Services
  4. click + Enable APIs and Services
  5. search for Firebase In-App Messaging API and make sure it's enabled.

You can also just search for messaging and make sure that all the cloud messaging APIs are enabled.

Kenton answered 5/6, 2022 at 3:18 Comment(7)
Everything you mentioned is right, but its not In-App Messaging API, its Cloud Messaging API. Anyhow thanks, it worked after Enabling.Kironde
Cloud Messaging API did it for meLathan
Thank you! Cloud Messaging API worked for me as well.Whenever
After API Enabled also same errorDamick
Have been wrestling with this hell for a couple of days! I don't know if I can thank you enough!Denise
That's nice and solves the problem! Can someone shed some light on how to integrate the "Firebase Cloud Messaging API (V1)" instead of using the "Cloud Messaging API (Legacy)"?Pedropedrotti
thanks. other service except Cloud Messaging was disabled. works now =)She
S
6

I had the same issue and since Cloud Messaging API (Legacy) is now deprecated I tried hard to get Firebase Cloud Messaging API (V1) to work.

I got lucky with using getMessaging(app).send() method instead .sendToTopic() or .sendToDevice() because those are using legacy api. More here: https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging.messaging.md#messaging_class

So in your case, this should work:

import admin from 'firebase-admin';
import { initializeApp } from 'firebase-admin/app'; // I recommend you use initializeApp instead because admin is legacy
import { getMessaging } from 'firebase-admin/messaging';
import serviceAccount from '<path-to-key>';

const fbApp = initializeApp({
    credential: admin.credential.cert(serviceAccount),
    projectId: '<PROJECT_ID>',
    databaseURL: '<DB_URL>'
});

const messaging = getMessaging(fbApp);

const sendPushNotifications2 = async (topic, reminder) => {
    // message is defined as [BaseMessage][1] extended by [topic][2] or [token][3] or [condition][4]
    const message = {
        ...reminder, // suppose reminder is BaseMessage
        topic: topic
    };
    
    await messaging.send(message);
};
Superfluous answered 29/6, 2023 at 11:58 Comment(2)
Please visitors, check out this answer and don't rely on old / deprecated APIs :D this is the way to go: Same message structure, just add a topic field to the message and you're done!Hinman
Came here to say the same, the sendToTopic is using the old API. You don't need to enable the old API that is going to be deprecated in 20/6/2024Latricialatrina
A
0

In june, 2024

Firebase removed : Cloud Messaging API (Legacy). you must use Firebase Cloud Messaging API (V1)

you have to generate new key from here : generate from here

Alight answered 9/7, 2024 at 12:51 Comment(1)
Would it be possible to update your answer to include a link to a relevant changelog or article that might be able to provide more information about the removal of this API?Rivalee

© 2022 - 2025 — McMap. All rights reserved.