使用firebase-functions-test测试Cloud Function遇Admin SDK初始化问题
问题解决:Firebase Admin初始化报错及数据库URL无法确定问题
问题重现
- 直接调用
getDatabase()/getFirestore()时抛出错误:
The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.
对应代码:
import { getDatabase } from 'firebase-admin/database'; import { getFirestore, Timestamp } from 'firebase-admin/firestore'; let defaultDatabase = getDatabase(); let defaultFirestore = getFirestore();
- 手动初始化后抛出错误:
Can't determine Firebase Database URL.
对应代码:
import { getDatabase } from 'firebase-admin/database'; import { getFirestore, Timestamp } from 'firebase-admin/firestore'; import { initializeApp } from 'firebase-admin/app'; const app = initializeApp(); let defaultDatabase = getDatabase(app); let defaultFirestore = getFirestore(app);
测试代码:
import { test } from "@jest/globals"; import { functionF} from "../../src/functionF"; import firebaseFunctionsTest from "firebase-functions-test"; const {wrap , firestore} = firebaseFunctionsTest({ projectId: 'project-id', databaseURL: "https://project-id.asia-southeast1.firebasedatabase.app", }, 'serviceAccount.json'); describe('test1', () => { test('test', () => { const wrappedFunctionF = wrap(functionF); const snap = firestore.makeDocumentSnapshot({ foo: 'bar' }, 'document/path'); wrappedFunctionF(snap); }); });
解决方案
问题核心是测试环境下Firebase Admin不会自动加载项目配置,需要显式指定数据库URL,同时避免重复初始化应用。
方案1:利用测试工具自动设置的环境变量初始化
firebase-functions-test初始化时传入的databaseURL会自动设置为FIREBASE_DATABASE_URL环境变量,函数代码中可以读取该变量完成初始化:
import { getDatabase } from 'firebase-admin/database'; import { getFirestore, Timestamp } from 'firebase-admin/firestore'; import { initializeApp, getApps } from 'firebase-admin/app'; // 检查是否已初始化应用,避免重复初始化报错 if (!getApps().length) { initializeApp({ databaseURL: process.env.FIREBASE_DATABASE_URL }); } let defaultDatabase = getDatabase(); let defaultFirestore = getFirestore();
方案2:显式传入完整配置(含凭证和数据库URL)
如果需要更明确的配置,可以直接传入service account和数据库URL:
import { getDatabase } from 'firebase-admin/database'; import { getFirestore, Timestamp } from 'firebase-admin/firestore'; import { initializeApp, getApps, cert } from 'firebase-admin/app'; // 注意serviceAccount.json的路径要正确 import serviceAccount from './serviceAccount.json'; if (!getApps().length) { initializeApp({ credential: cert(serviceAccount), databaseURL: "https://project-id.asia-southeast1.firebasedatabase.app" }); } let defaultDatabase = getDatabase(); let defaultFirestore = getFirestore();
关键注意点
- 必须使用
getApps().length检查应用是否已初始化,否则多次调用会抛出重复初始化的错误 - 测试环境下,
firebase-functions-test会自动注入环境变量,无需硬编码配置;生产环境中,Firebase会自动加载项目配置,代码无需修改即可兼容
内容的提问来源于stack exchange,提问作者flutroid
相关产品推荐
相关产品推荐

