我想在本地测试我的Firebase函数。 这些功能可以进行Firestore查询。
因此,我启动了仿真器firebase emulators:start
,在我的客户端中,我使用了firebase.functions().useFunctionsEmulator('http://localhost:5001')
。
当我在客户端中调用函数时,它们的功能运行良好。我可以在Firestore模拟器中读取/写入数据。
问题:
我想直接在客户端内部读取Firestore模拟器数据,例如:
firebase.firestore().collection('tests').get().then(tests => {
console.log( tests.docs.map(test=>test.map) )
})
但是我找不到如何在客户端中设置Firestore模拟器。
这是我尝试过的:
1)Firestore设置
firebase.firestore().settings({
host:'http://localhost:8080',
ssl:false
})
结果:
我在客户端控制台中获得了@firebase/firestore: Firestore (6.3.5): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
。
http请求返回“未找到”
2)在我的firebaseConfig中设置模拟器网址
var firebaseConfig = {
// ...
databaseURL: "http://localhost:8080",
// ...
}
firebase.initializeApp(firebaseConfig)
在这种情况下,请求远程服务器(https://firestore.googleapis.com.。)。
所以我想设置以下两种情况之一:
1)在函数仿真器中使用远程Firestore
OR
2)在我的客户端代码中使用本地Firestore模拟器。
任何人都已经做到了吗?
答案 0 :(得分:2)
npm i -D @firebase/testing
firebase setup:emulators:firestore
firebase serve --only firestore
const firebase = require("@firebase/testing");
// Helper function to setup test db
function authedApp(auth) {
return firebase
.initializeTestApp({ projectId: FIRESTORE_PROJECT_ID, auth })
.firestore();
}
// Setup methods
beforeEach(async () => {
// Clear the database between tests
await firebase.clearFirestoreData({ projectId: FIRESTORE_PROJECT_ID });
});
// Clean up apps between tests.
afterEach(async () => {
await Promise.all(firebase.apps().map(app => app.delete()));
});
it("should retrieve correct item", async () => {
// Init test db
const db = authedApp(null);
// Manually add item to collection
const ref = await db.collection(COLLECTION_NAME).add({name: 'test item'});
// Fetch item by id
const resp = await db.collection(COLLECTION_NAME).doc(ref.id).get();
// test the output
expect(resp).toBeDefined();
expect(resp).toEqual(expect.objectContaining({name: 'test item'}));
});
当然,您的特定设置和情况会有所不同,但这至少应该为您提供一个总体思路。更多信息:https://firebase.google.com/docs/rules/unit-tests
来自“ Test your Cloud Firestore Security Rules”的注释
写入Cloud Firestore模拟器的数据将保留在内存中,直到 仿真器已停止。如果仿真器连续运行,则可能 对测试隔离有影响。确保将数据写入一个 测试不在另一个中读取,或者使用
clearFirestoreData
,或为每个项目分配不同的项目ID 独立测试:调用firebase.initializeAdminApp或 firebase.initializeTestApp,附加用户ID,时间戳或随机 projectID的整数。
答案 1 :(得分:1)
我也有同样的问题。我找到了以下示例,看起来它仍在进行中:
https://github.com/firebase/quickstart-nodejs/tree/master/firestore-emulator/browser-quickstart
在示例中,他们没有直接使用@firebase/testing
。当我确实尝试将@firebase/testing
嵌入到我的Webpack代码中时,它尝试通过grpc
进行连接,而尝试进行fs.existsSync
的连接,这在webpack
浏览器上下文中不存在。他们宁愿通过WebChannel启用该功能。
截至2019年11月的一些警告:
@firebase/firestore: Firestore (6.3.5): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
尽管存在这些错误,我的函数仍然能够连接到本地Firestore。
我测试时使用的版本:
更新11/18:
quickstart-nodejs
github中提出了一个问题,看来我只需要使用所有内容的最新版本。 版本:
答案 2 :(得分:1)
好吧,这很简单...在Firestore的科学配置中,您应该提供主机,而不是Firestore的来源(使用ssl
参数设置协议):
firebase.firestore().settings({
host: 'localhost:8080',
ssl: false
})
当我遇到完全相同的错误时,至少这为我解决了这个问题。
仅供参考,对于正在阅读此书的任何人-如果您在Firestore客户端中遇到问题,都可以使用debug
级日志记录,只需设置firebase.firestore.setLogLevel('debug')
。如果OP做到了这一点,他可能已经注意到firebase正在访问http://http://localhost:8080/
...上的firestore ...
答案 3 :(得分:0)
好吧,我找到了怎么做:
1)在本地启动功能仿真器:
set GOOGLE_APPLICATION_CREDENTIALS=./privatekey.json && firebase serve --only functions
2)然后是客户端:
if (process.env.NODE_ENV === 'development') {
firebase.functions().useFunctionsEmulator('http://localhost:5001')
}
答案 4 :(得分:0)
定义FIRESTORE_EMULATOR_HOST环境变量
如果使用的库支持FIRESTORE_EMULATOR_HOST环境变量,请运行:
导出FIRESTORE_EMULATOR_HOST = localhost:8080
或只需将 FIRESTORE_EMULATOR_HOST = localhost:8080 添加到您的.env文件中