Я создал базу данных Firestore и хочу выполнять операции CRUD, используя свой бэкэнд NestJS (Node.js ofc). Я добавил Firebase в NestJS и (я полагаю) правильно настроил. Я использую учетную запись администратора SDK, правило базы данных Firestore заблокировано. Всякий раз, когда я пытаюсь проверить соединение (локально или в производстве), приложение Firebase успешно инициализируется, но кажется, что коллекция/документ не существует или по какой-то причине я не могу к нему подключиться.
Подробности. часть моего пакета pestjs.json (там есть пакет Firebase):
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/platform-express": "^10.0.0",
"bcrypt": "^5.1.1",
"firebase-admin": "^12.1.1",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
}
Я создал файл службы Firebase для инициализации приложения и выхода из системы в случае ошибок:
import { Injectable, OnModuleInit } from '@nestjs/common';
import * as admin from 'firebase-admin';
import * as serviceAccount from 'myserviceaccount.json';
@Injectable()
export class FirebaseService implements OnModuleInit {
private firestore: FirebaseFirestore.Firestore;
async onModuleInit() {
//checks if firestore is already initialized, if not, do so
if (admin.apps.length === 0) {
admin.initializeApp({
credential: admin.credential.cert(
serviceAccount as admin.ServiceAccount,
),
});
console.info('Firebase initialized successfully');
} else {
console.info('Firebase already initialized');
}
this.firestore = admin.firestore();
//check if database is connected:
try {
const docRef = this.firestore.doc('mycollection/mydocument');
const snapshot = await docRef.get();
if (snapshot.exists) {
console.info('Document data:', snapshot.data());
} else {
console.info('No such document!');
}
} catch (error) {
console.error('Error fetching document:', error);
}
}
getFirestore() {
return this.firestore;
}
}
А вот сервис NestJS, который выполняет crud-операции:
import { Injectable } from '@nestjs/common';
import { FirebaseService } from '../firebase.service';
@Injectable()
export class StampService {
private firestore: FirebaseFirestore.Firestore;
constructor(private readonly firebaseService: FirebaseService) {
this.firestore = this.firebaseService.getFirestore();
}
async testFirestoreConnection(): Promise<any> {
try {
const docRef = this.firestore.doc('mycollection/mydocument')
const snapshot = await docRef.get();
console.info(snapshot.data().fieldname);
return snapshot.data();
} catch (error) {
console.error('Firestore test error:', error);
throw new Error('Firestore test failed');
}
}
}
Когда я запускаю «nest start watch», я получаю следующую ошибку:
Firebase initialized successfully
Error fetching document: Error: 5 NOT_FOUND:
at callErrorFromStatus (path\node_modules\@grpc\grpc-js\src\call.ts:82:17)
at Object.onReceiveStatus (path\node_modules\@grpc\grpc-js\src\client.ts:611:51)
at Object.onReceiveStatus (path\node_modules\@grpc\grpc-js\src\client-interceptors.ts:419:48)
at path\node_modules\@grpc\grpc-js\src\resolving-call.ts:163:24
at processTicksAndRejections (node:internal/process/task_queues:77:11)
for call at
at ServiceClientImpl.makeServerStreamRequest (path\node_modules\@grpc\grpc-js\src\client.ts:594:42)
at ServiceClientImpl.<anonymous> (path\node_modules\@grpc\grpc-js\src\make-client.ts:189:15)
at path\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:237:29
at path\node_modules\google-gax\build\src\streamingCalls\streamingApiCaller.js:38:28
at path\node_modules\google-gax\build\src\normalCalls\timeout.js:44:16
at Object.request (path\node_modules\google-gax\build\src\streamingCalls\streaming.js:377:40)
at makeRequest (path\node_modules\retry-request\index.js:159:28)
at retryRequest path\node_modules\retry-request\index.js:119:5)
at StreamProxy.setStream (path\node_modules\google-gax\build\src\streamingCalls\streaming.js:368:37)
at StreamingApiCaller.call (path\node_modules\google-gax\build\src\streamingCalls\streamingApiCaller.js:54:16)
Caused by: Error:
at Firestore.getAll (path\node_modules\@google-cloud\firestore\build\src\index.js:1007:23)
at DocumentReference.get (path\node_modules\@google-cloud\firestore\build\src\reference\document-reference.js:180:32)
at FirebaseService.onModuleInit (path\src\firebase.service.ts:26:37)
at MapIterator.iteratee (path\node_modules\@nestjs\core\hooks\on-module-init.hook.js:22:43)
at MapIterator.next (path\node_modules\iterare\src\map.ts:9:39)
at IteratorWithOperators.next (path\node_modules\iterare\src\iterate.ts:19:28)
at Function.from (<anonymous>)
at IteratorWithOperators.toArray (path\node_modules\iterare\src\iterate.ts:227:22)
at callOperator (path\node_modules\@nestjs\core\hooks\on-module-init.hook.js:23:10)
at callModuleInitHook (path\node_modules\@nestjs\core\hooks\on-module-init.hook.js:43:23) {
code: 5,
details: '',
metadata: Metadata {
internalRepr: Map(1) { 'x-debug-tracking-id' => [Array] },
options: {}
}
}
Я не мог много попробовать. Я проверил json сервисной учетной записи, чтобы узнать, содержит ли он правильный идентификатор сервисной учетной записи и правильный идентификатор проекта.
Я добавил журналы консоли и попробовал блоки catch, показанные выше, чтобы хотя бы получить что-нибудь и понять, в чем проблема.
Я позаботился о том, чтобы ссылки на мою коллекцию и документы были точными и не содержали опечаток.
Я убедился, что FirebaseModule находится в моем app.module в качестве импорта.
FirebaseModule даже импортируется в модуль, которому принадлежит служба CRUD.
Что-то не так с тем, как я настроил Firebase/Firestore в NestJs, я неправильно настроил базу данных Firestore в консоли Firebase? Это что-то еще?
Любая помощь приветствуется!
Кажется, я знаю, в чем была проблема. OnModuleInit Firebase.service установлен как асинхронный, И метод службы NestJS, выполняющий операцию CRUD, также является асинхронным, поэтому вполне возможно, что метод CRUD завершится быстрее, чем onModuleInit в службе Firebase.
Необходимо встроить проверки в метод службы NestJS, чтобы увидеть, инициализировано ли приложение Firebase, и позволить ему выполнять операцию CRUD, только если это так. Это решило проблему.