错误:无法加载默认凭据(Firebase函数到Firestore)

时间:2019-09-27 04:27:48

标签: firebase google-cloud-firestore google-cloud-functions google-oauth firebase-cli

我正在尝试为Firebase Cloud Functions编写一个onCall函数,该函数在Firestore数据库上执行高级查询任务(即,根据AutoML自然lang检查文本查询以获取类别,等等),但是尝试时遇到问题从函数查询数据库:

Error getting documents ::  Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
    at GoogleAuth.getApplicationDefaultAsync (/srv/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)

功能:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

exports.query = functions.https.onCall((data, context) => {
    const text = data.text;
    var results = [];
    const promise = db.collection('providers').get()
    promise.then((snapshot) => {
        console.log('marker');
        snapshot.forEach((doc) => {
            results.push({id: doc.id, data: doc.data()});
        });
        console.log('yessir');
        return {results: results};
    }).catch((err) => {
        console.log('Error getting documents :: ', err)
        console.log('nosir');
        return {results: "no results"};
    });
});

更长的输出:

Function execution started
Function execution took 8ms, finished with status code: 200
Error getting documents :: (etc, same error)
nosir

示例2(运行中无变化):

Function execution started
Function execution took 1200 ms, finished with status code: 200
marker
yessir

我不知道此问题来自何处或如何解决。 有帮助吗?

致谢。

19 个答案:

答案 0 :(得分:26)

我要解决的问题是将firebase admin sdk密钥添加到我的项目中。

我在

下载了它
  

https://console.firebase.google.com/u/0/project/ 您的PROJECT_ID /设置/服务帐户/ adminsdk

Admin SDK Key Download Page

然后在admin.initializeApp();,我更改为:

admin.initializeApp({
    credential: admin.credential.cert(require('../keys/admin.json'))
});

我的文件夹结构是

├── key
│   ├── admin.json
├── src
│   ├── index.ts

答案 1 :(得分:7)

我遇到了同样的错误“无法加载默认凭据”。

使用npm update更新我的项目依赖项后发生了错误。 更准确地说,是 firebase-admin firebase-functions

更新前:

"dependencies": {
    "@google-cloud/firestore": "^1.3.0",
    "firebase-admin": "~7.0.0",
    "firebase-functions": "^2.2.0"
}

更新后:

"dependencies": {
    "@google-cloud/firestore": "^1.3.0",
    "firebase-admin": "^8.6.0",
    "firebase-functions": "^3.3.0"
}

我将serviceAccountKey.json添加到了我的项目中,并使用了我的Firebase项目的服务帐户设置中提供的代码更改了导入。

发件人:

var admin = require('firebase-admin')

admin.initializeApp()

收件人:

var admin = require('firebase-admin');    
var serviceAccount = require('path/to/serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://my-project.firebaseio.com'
});

请参阅下面的@Fernando Rocha答案以访问您的Firebase项目的帐户设置。

答案 2 :(得分:5)

@aldobaie的回答帮助我弄清楚了我的用例正在发生什么。对于那些不想在所有呼叫中添加异步/等待的人,请记住,firestore呼叫会返回promise,因此在它们前面加上return具有相同的效果。

就我而言:

function doSomething(...) {
    return admin.firestore().collection(...).doc(...).get()
        .then((doc) => {...})
        .catch(err => {...})
}

module.exports = functions.firestore.document('collection/{docId}').onWrite((change, context) => {
    return doSomething()
})

我认为接受的答案与Firebase的推荐配置背道而驰。函数环境已经可以访问管理员凭据,因此不建议在代码中传递密钥。

我这样做是这样的:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)

答案 3 :(得分:4)

我自己也遇到了同样的问题。有时,函数可以正常工作,并且通过Error: Could not load the default credentials错误会多次起作用。 我认为通过观察回调已解决了该问题。您必须保持函数运行,直到使用awaitasync前缀调用回调为止。

Firebase Cloud Functions不允许在终止后通过回调访问处理器!这就是为什么我们会收到Error: Could not load the default credentials错误。

因此,只要您在.then() function前面加上await,并在其中包含函数,就在async前面加上对函数的任何调用,就在await前面。 / p>

async function registerUser(..) {
    ...
    await admin.firestore().collection(..)...
    ...
}

希望这对您有所帮助!

答案 4 :(得分:2)

另一种选择是set the service account key in an environmental variable,而不是通过调用firebaseAdmin.initializeApp({ credential })来设置。

Linux

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json"

Windows PowerShell

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\[FILE_NAME].json"

后记:一个更好的选择可能是use the local emulator suite

答案 5 :(得分:2)

好吧,所以我也遇到了这个错误,花了几天的时间沮丧地浏览了多个站点,文章,视频等,试图找出导致此问题的原因,这样我才能为自己和每个人都得到一个适当的答案谁在挣扎。

此线程中已经有此问题的答案。但是,我尝试跟踪其中的大多数都无济于事。有些存在安全问题,而另一些则含糊其词。我决定发布一个详尽的答案,该答案还解决了您遵循其他一些答案时可能遇到的安全问题。

好了,现在我已经开始使用吧!

首先,您需要转到此链接-Getting started with authentication

您应该在屏幕中央看到它- Getting Started with Authentication 接下来,点击我标记为绿色的按钮。这将带您进入创建服务帐户密钥页面。

您应该看到与下图类似的屏幕- enter image description here

  • 对于服务帐户选项,选择新的服务帐户。

  • 为您的服务帐户创建一个名称。这并不重要,可以随便命名。

  • 对于角色选项,选择 Project-> Owner

  • 最后,为密钥类型选择JSON选项,然后单击create。

这应该创建并下载.json文件。将此文件放置在安全可靠的地方。我在项目的根目录下创建了一个名为“ credentials”的文件夹,并将其放置在该文件夹中。

我还将该文件重命名为更具可读性的文件。尽管这不是必需的,但遵循良好的文件/文件夹命名和结构化做法很重要,我建议您将其重命名为更易读的名称。

(请注意,此文件是个人文件,不应包含在任何github存储库/ firebase production / etc中。此文件仅供您和您使用!)

下一步打开命令提示符窗口,然后键入以下命令-

设置GOOGLE_APPLICATION_CREDENTIALS = C:\ Users \ Username \ Path \ To \ File \ filename.json

这将创建一个安全链接到您的凭据的环境变量,当您进行身份验证呼叫时,firebase会识别并使用该凭据。

(注意-这是Windows的命令。如果您使用的是Mac / Linux,请转到前面提到的“身份验证入门” 页,以获取适用于您的操作系统的命令)

可以,现在应该解决此问题。如果有人有其他疑问或问题,请在下面发表评论,我会尽力为您提供帮助。我知道被这样的错误困住会令人沮丧。

我希望这至少对某人有帮助。编程愉快。 加德(C.Gadd)

答案 6 :(得分:1)

即使没有问题,我也不想使用@Fernando解决方案。

我有prd和non-prd环境。我使用firebase use命令将更改推送到正确的环境。部署时,firebase使用默认服务帐户。我也不想在项目文件夹或git repo中拥有密钥。

我解决的方法可能不适用于其他人,但想在这里分享。

当我更新firebase项目的权限以授予查看者编辑权限时,出现了问题。我让那个人成为所有者,然后回滚给编辑。它消失了。它不是解决问题的正当理由,但对我有用,我不必下载密钥。

答案 7 :(得分:1)

我在firebase中遇到了同样的问题错误:“无法获取默认凭据。”

然后转到 firebase控制台,然后转到项目设置,您可以在其中找到服务帐户选项。单击此处,您将在项目设置下看到生成新私钥。 复制项目语言的代码并将其添加到项目文件中。

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

生成密钥后,您将可以选择下载。并将其放在项目文件夹中。同时设置路径{{1}} 这就是您准备好了。

答案 8 :(得分:1)

这是Firebase中的已知错误。在此处查看进度:https://github.com/firebase/firebase-tools/issues/1940

但是,与此同时,解决这一问题的方法很少:

1通过代码明确传递

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

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

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

不推荐此硬编码。无法在服务器上访问此json文件。

2通过GOOGLE_APPLICATION_CREDENTIALS

我建议采用这种方式,设置环境变量:

GOOGLE_APPLICATION_CREDENTIALS=path/to/serviceAccountKey.json

对于Windows :(考虑json位于项目的根路径。

使用powershell:

$env:GOOGLE_APPLICATION_CREDENTIALS='serviceAccountKey.json'

使用NPM脚本:(请注意&&之前没有空格)

"serve": "set GOOGLE_APPLICATION_CREDENTIALS=serviceAccountKey.json&& npm run start",

(由于某些原因cross-env无效)

3由于gcloud而在知名文件系统路径上可用
通过安装gcloud sdk并运行gcloud auth application-default login

4在GCP上运行时可从Compute Engine元数据API获得

答案 9 :(得分:1)

admin.initializeApp(functions.config().firebase);

也可以。

答案 10 :(得分:1)

当云功能未正确终止时,也会发生此错误。

每当编写云函数时,请确保在云函数处理结束后返回promise,以便云函数知道您的过程已完成。

如果您不返回承诺,那么云功能可能会在处理完成之前终止。

您可以参考此文件以了解如何终止云功能。 Terminate cloud functions

答案 11 :(得分:1)

我有同样的问题。

  • 在Firebase =>服务和帐户上进入设置页面。

  • Firebase设置1.参数2.帐户3.下载文件并将其重命名为[admin.json]

  • 复制代码并粘贴

  • 需要“ admin.json”并粘贴,然后运行Firebase deploy。

答案 12 :(得分:0)

在文档中很难找到的一件事是 firebase-admin SDK 仅在 环境变量 告诉它时才使用模拟器。如果您使用此处某些答案中所述的服务帐号 JSON 密钥,firebase-admin 将与 prod(在 Google Cloud 上)对话,而不是模拟版本,即使您正在执行的其他所有操作都在模拟器上。

因为您很可能更愿意使用模拟器进行本地测试,以下是我在 Mac ~/.zshrc 中设置环境变量的方法:

export GCLOUD_PROJECT="your-project-id"
export FIRESTORE_EMULATOR_HOST=localhost:8080
export FIREBASE_AUTH_EMULATOR_HOST=localhost:9099
export FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000

GCLOUD_PROJECT ID 可能是您的项目 ID,但显然任何 ID 都可以使用,只要它是格式正确的 Firebase 项目 ID,因此这些相同的环境变量可用于在 Firebase 模拟器上测试您的所有项目。在尝试任何其他解决方案之前,请先尝试设置这些环境变量以供模拟器使用。

另一个奇怪的是 firebase emulators:start 需要设置这些环境变量,但 firebase emulators:exec 会自动设置它们。当您处于 CI 场景时 :exec 是更好的选择,但是当您在编写代码时主动运行测试时让模拟器保持运行并使用 :start 是一个更快的循环,您需要环境变量才能正常工作.通过将这些放在环境变量中,您的代码在部署到云端时根本不需要更改。

答案 13 :(得分:0)

对于那些在下载了帐户密钥并在代码中使用它之后仍然遇到相同问题事件的人,请确保该事件位于您的functions文件夹中。

答案 14 :(得分:0)

在MacOS上,我必须执行以下操作:

我收到凭证错误,因为本地运行的功能模拟器无法安全地与生产环境中运行的firebase auth通信。

Google Cloud Reference

答案 15 :(得分:0)

以上都不是。 您可能只是:

firebase登录-它将打开浏览器登录

登录后,立即返回控制台并运行:

firebase初始化-将成功运行。

答案 16 :(得分:0)

我只是遇到了同样的问题。要解决此问题,只需在project-dir / functions /目录中通过npm update更新节点包。最后,再次部署。

答案 17 :(得分:0)

对于那些从农奴那里来的人,他们想弄清楚他们的Google云功能为何失败:

错误:无法加载默认凭据。浏览到 https://cloud.google.com/docs/authentication/getting-started了解更多 信息。在GoogleAuth.getApplicationDefaultAsync

但以上方法均无济于事,您可以尝试更新所有@google/whatever依赖项(?): npm i -E @google/firestore@latest。然后重建,部署,再试一次。 最近发生在我身上几次,并且有效。

答案 18 :(得分:0)

将您的Firebase服务帐户下载到您的项目中,并像这样引用它:

<code>
  var admin = require("firebase-admin");
  var serviceAccount = require("path/to/serviceAccountKey.json");

  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "<database-url>"
  });
</code>