Ответ 1
У меня была похожая проблема. Вероятно, это ошибка в версии 7.0.2
firebase-tools
. Я откатился до версии 7.0.0
и теперь она работает.
Итак, временное решение:
npm i [email protected] -g
Я пытаюсь создать облачную функцию Firebase. Так что я бы запустил локальную облачную функцию Firebase. Но это не работает, как настроить аутентификацию.
Я установил инструменты firebase: https://firebase.google.com/docs/functions/local-emulator. Я запустил команду firebase login
, так что теперь я вошел в систему. Затем я создал свой ключ json с помощью этого учебника: https://cloud.google.com/docs/authentication/getting-started Теперь, если я echo $GOOGLE_APPLICATION_CREDENTIALS
результат будет /home/$USER/.google/****.json
которые содержат
"project_id","private_key_id","private_key","client_email", "client_id", "auth_uri", "token_uri", "auth_provider_x509_cert_url", "client_x509_cert_url"
Также я попытался установить полную gcloud auth application-default login
Google Cloud SDK и gcloud auth application-default login
: gcloud auth application-default login
но безуспешно.
Версии пакета Npm:
"firebase-functions":"3.0.2"
"firebase-admin": "8.2.0"
Я думаю, что предоставил достаточно информации, но не стесняйтесь спрашивать меня больше, если хотите.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const express = require("express");
const app = express();
app.get("/", async (req, res) => {
admin.firestore().collection('something').get().then((collection) =>
return res.send({"count": collection.docs.length, "status": 200});
});
exports.exports = functions.https.onRequest(app);
код не важен, самое главное, что даже когда я выполнил все эти шаги, когда я локально эмулирую свою базу Firebase с firebase serve
и запускаю функцию, у меня появляется эта ошибка: Ошибка: входящий объект JSON не содержит поле client_email
Я могу убедиться, что файл json содержит поле client_email.
Можете ли вы помочь мне пройти аутентификацию в Google?
Спасибо за вашу помощь.
У меня была похожая проблема. Вероятно, это ошибка в версии 7.0.2
firebase-tools
. Я откатился до версии 7.0.0
и теперь она работает.
Итак, временное решение:
npm i [email protected] -g
Короче:
admin.initializeApp({ credential: admin.credential.applicationDefault() });
Смотрите документы для admin.credential.applicationDefault()
Обновление: обратите внимание, что это рекомендуется только для тестирования/эксперимента:
Эта стратегия полезна при тестировании и экспериментах, но может затруднить определение учетных данных, используемых вашим приложением. Мы рекомендуем явно указать, какие учетные данные следует использовать приложению,... Source
Немного больше информации
У меня было то же самое при попытке вызвать локально функцию firebase, которая пытается обновить некоторые документы в базе данных firestore в пакетном режиме. (Не тестировал без партии).
Чтобы начать локально вызывать функции firebase, я использую:
firebase function:shell
Как вы, вероятно, знаете, здесь перечислены доступные функции для вашего проекта.
Я вызвал свою функцию и получил следующую ошибку callstack:
Unhandled error Error: The incoming JSON object does not contain a client_email field
> at JWT.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\jwtclient.js:165:19)
> at GoogleAuth.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:294:16)
> at GoogleAuth.getClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:476:52)
> at GrpcClient._getCredentials (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:107:40)
> at GrpcClient.createStub (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:223:34)
> at new FirestoreClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:128:39)
> at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:315:26)
> at ClientPool.acquire (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:61:35)
> at ClientPool.run (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:114:29)
> at Firestore.readStream (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:995:26)
RESPONSE RECEIVED FROM FUNCTION: 500, {
"error": {
"status": "INTERNAL",
"message": "INTERNAL"
}
}
Я выполнял свою функцию локально, используя командную строку: firebase functions:shell
Я использовал этот код:
// Reference report in Firestore
const db = admin.firestore();
admin.initializeApp();
export const performMyCallableFirebaseFunction = (db, { from, to }) => {
return db.collection("collectionName").where("prop", "==", from).limit(500).get().then(snapshot => {
if (snapshot.empty) return new Promise(resolve => resolve('No docs found with prop: ${from}'));
const batch = db.batch();
snapshot.forEach(doc => batch.update(doc.ref, { prop: to }));
return batch.commit();
});
};
exports.myCallableFirebaseFunction = functions.https.onCall(data => performMyCallableFirebaseFunction(db, data.from, data.to));
Я изменил линию
admin.initializeApp();
в
admin.initializeApp({ credential: admin.credential.applicationDefault() });
и теперь я смог вызвать свою функцию локально, используя:
firebase functions:shell
firebase > myCallableFirebaseFunction({from: "foo", to: "bar"})
Смотрите документы для admin.credential.applicationDefault()
Вероятно, вам нужно настроить Firebase Admin SDK для использования эмулятора Firebase. Это можно сделать, передав свойство credential
при вызове admin.initializeApp()
:
const serviceAccount = require('../serviceAccount.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
Вы можете скачать JSON файл своей учетной записи службы в консоли Firebase:
Создав проект Firebase, вы можете инициализировать SDK с помощью стратегии авторизации, которая объединяет файл учетной записи службы и учетные данные приложения Google по умолчанию.
Чтобы аутентифицировать учетную запись службы и разрешить ей доступ к службам Firebase, необходимо сгенерировать файл закрытого ключа в формате JSON.
Чтобы создать файл личного ключа для вашей учетной записи службы:
В консоли Firebase откройте "Настройки"> "Учетные записи служб".
Нажмите "Создать новый закрытый ключ", затем подтвердите, нажав "Создать ключ".
Надежно храните файл JSON, содержащий ключ.
Задайте для переменной среды GOOGLE_APPLICATION_CREDENTIALS путь к файлу JSON, в котором содержится ключ учетной записи службы. Эта переменная применяется только к текущему сеансу оболочки, поэтому, если вы открываете новый сеанс, установите переменную снова.
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
Я получал эту ошибку при запуске firebase emulators:start
.
Согласно исследованию этой ошибки: https://github.com/firebase/firebase-tools/issues/1451, кажется, что это проблема с обращением к приложению напрямую, а не через модуль администратора.
то есть это вызывает ошибку:
const app = admin.initializeApp();
const firestore = app.firestore();
но это не
admin.initializeApp();
const firestore = admin.firestore();
Однако для первоначального вопроса вы используете admin.firestore(), чтобы не было проблем. Кажется, что admin.initializeApp()
никогда не вызывается. Возможно, это может быть причиной вашей проблемы?
Вот как я решил проблему после нескольких часов борьбы:
Короткий ответ:
Создать ключ Firebase-adminsdk
Как это сделать:
Перейдите в Google-console > Service accounts
https://console.cloud.google.com/projectselector2/iam-admin
Выберите свой проект
firebase-admin-sdk
похож на [email protected]
Create key
и выбрать JSON
.json
. Который имеет ProjectID, PrivateKey and ClientEmail
в нем// Providing a service account object inline
admin.initializeApp({
credential: admin.credential.cert({
projectId: "<PROJECT_ID>",
clientEmail: "[email protected]<PROJECT_ID>.iam.gserviceaccount.com",
privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
})
});