【问题标题】:Firebase Admin SDK: Not fetching access tokenFirebase Admin SDK:未获取访问令牌
【发布时间】:2019-12-05 11:51:55
【问题描述】:

目标是让我的快递服务器使用 Firebase 云消息传递 (FCM) 发送推送通知。

问题是 admin SDK 的初始化似乎不起作用。 代码用 JavaScript 编写,node 版本为 10.16.0,firebase-admin 版本为 8.3.0,Server 运行在最新的 Ubuntu 上。

我按照 firebase 指南设置了管理 SDK: https://firebase.google.com/docs/admin/setup#initialize_the_sdk

已设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量,并尝试使用该变量打开文件:

nano $GOOGLE_APPLICATION_CREDENTIALS

一次

admin.messaging().send(message)

被调用,抛出如下错误:

Error sending message: { Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal metadata.google.internal:80. Error code: ENOTFOUND".
    at FirebaseAppError.FirebaseError [as constructor] (/local/home/user/node_modules/firebase-admin/lib/utils/error.js:42:28)
    at FirebaseAppError.PrefixedFirebaseError [as constructor] (/local/home/user/node_modules/firebase-admin/lib/utils/error.js:88:28)
    at new FirebaseAppError (/local/home/user/node_modules/firebase-admin/lib/utils/error.js:122:28)
    at /local/home/user/node_modules/firebase-admin/lib/firebase-app.js:121:23
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errorInfo:
   { code: 'app/invalid-credential',
     message:
      'Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal metadata.google.internal:80. Error code: ENOTFOUND".' },
  codePrefix: 'app' }

实施非常严格地遵循 Firebase 指南。

类似的问题指向不支持云功能的 spark 计划。但据我了解,我正在尝试使用云消息传递而不是云功能。

我不知道出了什么问题。特别是因为它与指南中的代码非常相似。 除了 firebase-admin,我还需要安装其他一些 firebase 组件吗?

服务器代码:


const express = require('express');


//firebase for notifications
const admin = require('firebase-admin');


admin.initializeApp({
    projectId: <projectId>,
    credential: admin.credential.applicationDefault(),
    databaseURL: "https://<projectId>.firebaseio.com"
});

// server set up removed


io.on('connection', socket => {

    socket.on('notification', (target, message) => {
        // This log is printed
        console.log("got notification for: ", target)
        // target = registration token comes from the client FCM SDKs.
        if (typeof (target) === "string") {
            sendNotifiaction(target, message)
        }
    });

});

function sendNotifiaction(registrationToken, message) {
    // This registration token comes from the client FCM SDKs.
    message.token = registrationToken

    // Send a message to the device corresponding to the provided
    // registration token.
    admin.messaging().send(message)
        .then((response) => {
            // Response is a message ID string.
            console.log('Successfully sent message:', response);
        })
        .catch((error) => {
            // Error catched here
            console.log('Error sending message:', error);
        });
}

服务帐户密钥(文件路径 = $GOOGLE_APPLICATION_CREDENTIALS)。 有些字段明显省略了。

{
  "type": "service_account",
  "project_id": "..",
  "private_key_id": "..",
  "private_key": "-----BEGIN PRIVATE KEY-----.."
  "client_email": "firebase-adminsdk-.....iam.gserviceaccount.com",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-......iam.gserviceaccount.com"
}

【问题讨论】:

  • 您将什么设置为凭证?
  • @andresmijares 我使用从 firebase 控制台 -> 设置 -> 服务帐户 -> 生成新私钥获得的服务帐户密钥。我关注了this guide
  • 一切对我来说似乎都是正确的,只是为了调试,如果您尝试在 admin.initializeApp 行之前记录 env 变量会发生什么?看看你的应用是否可以访问该变量
  • 谢谢。似乎问题在于找不到文件。我对位置进行了硬编码,它起作用了。 (我之前尝试过这种方式没有成功,也许我有一个错字......)。不过再次感谢您的帮助。

标签: node.js firebase firebase-cloud-messaging firebase-admin


【解决方案1】:

解决方案

我只是使用了firebase控制台提供的代码示例(设置->服务帐户)。

注意:我之前尝试过,但没有成功:因此请检查路径是否正确以及您的服务器是否有权访问它。

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://<ProjectId>.firebaseio.com"
});

【讨论】:

  • 我必须使用GOOGLE_APPLICATION_CREDENTIALS 导出凭据才能使其正常工作,但在我的情况下,我使用的是模拟器命令firebase functions:shell
  • 这对我有用,但是,我想知道 (1) 存储该密钥,(2) 根据开发与生产环境切换此代码的好方法。
  • @Zorayr 我也在试图弄清楚这一点,在这方面花费了太多时间:/
  • @Zorayr 我想我真的想通了。这是一个指向我最终为我做的和为我工作的要点的链接:gist.github.com/corasan/330bfd5549dc25eaa694b8ea39fca960
猜你喜欢
  • 1970-01-01
  • 2019-12-17
  • 2020-08-06
  • 2018-09-09
  • 2018-09-30
  • 2019-09-24
  • 2017-07-30
  • 2013-02-22
  • 2015-10-11
相关资源
最近更新 更多