簡體   English   中英

錯誤:無法加載默認憑據(Firebase function 到 firestore)

[英]Error: Could not load the default credentials (Firebase function to firestore)

我正在嘗試為 Firebase Cloud Functions 編寫一個 onCall function,它在 firestore 數據庫上執行高級查詢任務(即根據 AutoML 自然語言檢查文本查詢以獲得類別等),但我一直在嘗試查詢時遇到問題來自 function 的數據庫:

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)

Function:

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"};
    });
});

更長的 output:

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

我不知道這個問題是從哪里來的,也不知道如何解決。 有什么幫助嗎?

問候。

首先要做的就是將我的 firebase admin sdk 密鑰添加到我的項目中。

我在下載

https://console.firebase.google.com/u/0/project/**YOUR_PROJECT_ID**/settings/serviceaccounts/adminsdk

管理員 SDK 密鑰下載頁面

然后在admin.initializeApp(); 我改為:

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

我的文件夾結構是

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

但是,正如一些人已經提到的那樣,一種更好的做法和更安全的方法:您可以使用環境變量來存儲您的憑據,這樣您就不會將其提交到諸如 Github 之類的存儲庫中,使其更安全地避免安全漏洞並且不會使它硬編碼。

根據您的項目以及您將在何處部署它,有不同的方法可以做到這一點。

有很多關於如何創建和訪問 env 變量的教程( 比如這個),但是你可以像下面的例子一樣使用它的名字:

GOOGLE_APPLICATION_CREDENTIALS="/home/admin.json"

我有同樣的錯誤“無法加載默認憑據”。

使用npm update更新我的項目依賴項后發生錯誤。 更准確地說是 firebase-adminfirebase-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 項目的帳戶設置。

@aldobaie 的回答幫助我弄清楚我的用例發生了什么。 對於那些不想在所有調用中添加 async/await 的人,請記住,firestore 調用 return 承諾,因此在它們前面加上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 的推薦配置背道而馳。 function 環境已經可以訪問管理員憑據,不建議在代碼中傳遞您的密鑰。

我這樣做:

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

我自己也遇到了同樣的問題。 有時 function 可以工作,而且很多時候會出現Error: Could not load the default credentials錯誤。 我相信通過觀察回調已經解決了這個問題。 您必須保持 function 運行,直到使用awaitasync前綴調用回調。

Firebase 雲函數一旦終止就不允許通過回調訪問處理器! 這就是為什么我們得到Error: Could not load the default credentials錯誤。

所以,只要你有一個.then() function前綴await它和前綴 function 它在它里面有async和前綴任何對await的調用。

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

我希望這可以幫助你!

另一種選擇是在環境變量中設置服務帳戶密鑰,而不是通過調用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"

后記:更好的選擇可能是使用本地模擬器套件

好的,所以我也遇到了這個錯誤,並且花了幾天的時間瀏覽多個網站、文章、視頻等,試圖找出這個問題的原因,這樣我就可以為自己和其他所有人都得到一個充分的答案掙扎。

這個問題已經有這個問題的答案了。 但是,我嘗試關注其中的大多數都無濟於事。 有些存在安全問題,有些則太模糊而無法遵循。 我決定發布一個詳盡的答案,該答案還解決了如果您遵循其他一些答案會遇到的安全問題。

好吧,現在我已經解決了這個問題,讓我們開始吧!

首先,您需要 go 到此鏈接 - 身份驗證入門

您應該在屏幕中央看到這個 - 身份驗證入門 接下來,單擊我標記為綠色的按鈕。 這將帶您進入創建服務帳戶密鑰頁面。

您應該會看到與下圖類似的屏幕 - 在此處輸入圖像描述

  • 對於服務帳戶選項,select 新服務帳戶。

  • 為您的服務帳戶創建一個名稱。 這個不重要,隨便取個名字就行。

  • 對於角色選項 select項目 -> 所有者

  • 最后,為密鑰類型選擇 select JSON 選項,然后點擊創建。

這應該創建並下載一個.json 文件。 將此文件放在智能且安全的地方。 我在項目的根目錄中創建了一個名為“credentials”的文件夾並將其放置在其中。

此外,我將文件重命名為更具可讀性的文件。 雖然這不是必需的,但遵循良好的文件/文件夾命名和結構實踐很重要,我建議您將其重命名為更具可讀性的名稱。

(請務必注意,此文件是個人文件,不應包含在任何 github 存儲庫/firebase 生產/等中。此文件僅供您和您一個人使用!)

接下來打開命令提示符 window 並輸入以下命令 -

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

這將創建一個環境變量,該變量安全地鏈接到您的憑據,firebase 在您進行身份驗證時將識別並使用該憑據。

(注意 - 這是 windows 的命令。如果您使用 mac/linux go 到前面提到的“驗證入門”頁面,以獲得適用於您的操作系統的適當命令)

go,問題現在應該得到解決。 如果有人有任何進一步的問題或問題,請隨時在下面發表評論,我會盡我所能為您提供幫助。 我知道陷入這樣的錯誤是多么令人沮喪。

我希望這至少可以幫助某人。 快樂編程。 C.Gadd

即使沒有任何問題,我也不想使用@Fernando 解決方案。

我有prd和非prd環境。 我使用 firebase 使用命令將更改推送到正確的環境。 當我部署時,firebase 使用默認服務帳戶。 此外,我不想在項目文件夾或我的 git 存儲庫中擁有密鑰。

我解決的方法可能對其他人不起作用,但想在這里分享。

當我更新 firebase 項目的權限以授予具有編輯權限的查看器時,我遇到了這個問題。 我讓那個人成為所有者並回滾到編輯器。 它走了。 它不能作為修復的理由,但對我有用,我不必下載密鑰。

我在 firebase 中遇到了同樣的問題錯誤:“無法獲得默認憑據。”

然后 go 到firebase 控制台和 go 到項目設置,您可以在其中找到服務帳戶選項。 單擊此處,您將在項目設置下看到生成新私鑰 復制項目語言的代碼並將其添加到項目文件中。

 var admin = require("firebase-admin"); var serviceAccount = require("path/to/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://your-database-url-that-is-given-under-admin-sdk-snippets" });

生成密鑰后,您將可以選擇下載。 並將其放在項目文件夾中。 還設置路徑var serviceAccount = require("path/to/serviceAccountKey.json"); 那就是你准備好了。

當雲 function 未正確終止時,也會出現此錯誤。

Whenever you write a cloud function make sure you return promise after the cloud function processing is over, so that cloud function knows that your process is complete.

如果您不返回 promise,那么您的雲 function 可能會在處理完成之前終止。

您可以參考此了解如何終止雲 function。 終止雲功能

我遇到過同樣的問題。

  • Go 在您的設置頁面上 Firebase => 服務和帳戶。

  • Firebase 設置 1. 參數 2. 賬號 3. 下載文件並重命名 [admin.json]

  • 復制代碼並粘貼

  • 需要“admin.json”並粘貼,然后運行 Firebase 部署。

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

也有效。

這是 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 獲得

將您的 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>

對於那些從 serp 來到這里試圖弄清楚為什么他們的谷歌雲 function 失敗的人:

錯誤:無法加載默認憑據。 瀏覽到https://cloud.google.com/docs/authentication/getting-started了解更多信息。 在 GoogleAuth.getApplicationDefaultAsync

但以上都沒有幫助,您可以嘗試更新所有(?)您的@google/whatever依賴項: npm i -E @google/firestore@latest 然后重建,部署,再試一次。 最近在我身上發生了幾次,這很有效。

我只是有同樣的問題。 要解決它,只需通過npm update您的項目目錄/功能/目錄中的節點包。 最后,再次部署。

以上都沒有。 你可能只是:

firebase 登錄 - 它將打開瀏覽器登錄

登錄后,返回控制台並運行:

firebase init - 它將成功運行。

在 MacOS 上,我必須執行以下操作:

export GOOGLE_APPLICATION_CREDENTIALS=/Users/myname/serviceAccountKey.json

我收到憑據錯誤,因為本地運行的功能模擬器無法安全地與生產中運行的 firebase auth 通信。

谷歌雲參考

對於那些在下載帳戶密鑰並在您的代碼中使用它后仍然遇到相同問題事件的人,請確保它在您的函數文件夾中。

在文檔中很難找到的一件事是 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 是一個更快的循環,您需要環境變量才能使其正常工作. 通過在環境變量中包含這些,您的代碼在部署到雲時根本不需要更改。

我剛遇到這個問題並用

firebase login

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM