Error: Firestore has already been initialized. You can only call settings() once, and only before calling any other methods on a Firestore object
Error: Firestore has already been initialized. You can only call settings() once, and only before calling any other methods on a Firestore object
所以我正在为 firebase 规则编写测试,这样我就可以为我在 Whosebug 上写的另一个问题创建可重现的代码,但我得到了这个错误:
$ mocha test2.js
Our social app
1) Can read a single public post
0 passing (245ms)
1 failing
1) Our social app
Can read a single public post:
Error: Firestore has already been initialized. You can only call settings() once, and only before calling any other methods on a Firestore object.
at Firestore.settings (node_modules\@google-cloud\firestore\build\src\index.js:434:19)
at getAdminFirestore (test2.js:41:9)
at Context.<anonymous> (test2.js:60:23)
at processImmediate (internal/timers.js:461:21)
它似乎不喜欢我在 getAdminFirestore 函数中使用 admin.settings(dbSettings)
但如果我将其注释掉,它就会抛出
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\Users\julien\Documents\GitHub\reloadium\test\test2.js)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
可能是因为找不到模拟器端口?
test2.js
/* eslint-env mocha */
const firebase = require('@firebase/rules-unit-testing');
const firestoreEmulatorPort = 8081;
const dbSettings = {
host: `localhost:${firestoreEmulatorPort}`,
ssl: false,
}
const MY_PROJECT_ID = "test";
const theirId = "user_xyz";
function getFirestore(
auth,
) {
var db = firebase.initializeTestApp(
{
projectId: MY_PROJECT_ID,
auth: auth
}
)
.firestore()
db.settings(
dbSettings
)
return (
db
)
}
function getAdminFirestore(
) {
var admin = firebase.initializeAdminApp(
{
projectId: MY_PROJECT_ID
}
)
.firestore()
admin.settings(
dbSettings
)
return (
admin
)
}
describe(
"Our social app",
(
) => {
it(
"Can read a single public post",
async (
) => {
const admin = getAdminFirestore();
const postId = "public_post"
const setupDoc = admin.collection(
"posts"
).doc(
postId
)
await setupDoc.set(
{
authorId: theirId,
visibility: "public"
}
)
const db = getFirestore(null)
const testRead= db.collection(
"posts"
).doc(
postId
)
await firebase.assertSucceeds(
testRead.get()
)
}
)
}
)
firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId}{
allow read:if (
(
resource.data.visibility == "public"
) ||
(
resource.data.authorId == request.auth.uid
)
);
}
}
}
我该如何解决这个问题?
我通过设置 firestore 模拟器端口环境变量解决了我的问题
FIRESTORE_EMULATOR_HOST=localhost:8081
而不是在
中设置端口
const firestoreEmulatorPort = 8081;
const dbSettings = {
host: `localhost:${firestoreEmulatorPort}`,
ssl: false,
}
db.settings(dbSettings)
我从我的代码中删除了这个
所以我正在为 firebase 规则编写测试,这样我就可以为我在 Whosebug 上写的另一个问题创建可重现的代码,但我得到了这个错误:
$ mocha test2.js
Our social app
1) Can read a single public post
0 passing (245ms)
1 failing
1) Our social app
Can read a single public post:
Error: Firestore has already been initialized. You can only call settings() once, and only before calling any other methods on a Firestore object.
at Firestore.settings (node_modules\@google-cloud\firestore\build\src\index.js:434:19)
at getAdminFirestore (test2.js:41:9)
at Context.<anonymous> (test2.js:60:23)
at processImmediate (internal/timers.js:461:21)
它似乎不喜欢我在 getAdminFirestore 函数中使用 admin.settings(dbSettings)
但如果我将其注释掉,它就会抛出
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\Users\julien\Documents\GitHub\reloadium\test\test2.js)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
可能是因为找不到模拟器端口?
test2.js
/* eslint-env mocha */
const firebase = require('@firebase/rules-unit-testing');
const firestoreEmulatorPort = 8081;
const dbSettings = {
host: `localhost:${firestoreEmulatorPort}`,
ssl: false,
}
const MY_PROJECT_ID = "test";
const theirId = "user_xyz";
function getFirestore(
auth,
) {
var db = firebase.initializeTestApp(
{
projectId: MY_PROJECT_ID,
auth: auth
}
)
.firestore()
db.settings(
dbSettings
)
return (
db
)
}
function getAdminFirestore(
) {
var admin = firebase.initializeAdminApp(
{
projectId: MY_PROJECT_ID
}
)
.firestore()
admin.settings(
dbSettings
)
return (
admin
)
}
describe(
"Our social app",
(
) => {
it(
"Can read a single public post",
async (
) => {
const admin = getAdminFirestore();
const postId = "public_post"
const setupDoc = admin.collection(
"posts"
).doc(
postId
)
await setupDoc.set(
{
authorId: theirId,
visibility: "public"
}
)
const db = getFirestore(null)
const testRead= db.collection(
"posts"
).doc(
postId
)
await firebase.assertSucceeds(
testRead.get()
)
}
)
}
)
firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId}{
allow read:if (
(
resource.data.visibility == "public"
) ||
(
resource.data.authorId == request.auth.uid
)
);
}
}
}
我该如何解决这个问题?
我通过设置 firestore 模拟器端口环境变量解决了我的问题
FIRESTORE_EMULATOR_HOST=localhost:8081
而不是在
const firestoreEmulatorPort = 8081;
const dbSettings = {
host: `localhost:${firestoreEmulatorPort}`,
ssl: false,
}
db.settings(dbSettings)
我从我的代码中删除了这个