我们正在测试使用 Web Worker 在后台处理某些 Firestore 查询。该过程有相当详细的记录,直到我们需要查询需要由我们的 Firestore 安全规则确定的用户身份验证的集合。即使用户已登录,这些集合也会响应“权限缺失或权限不足”错误,因为用户的身份验证状态在工作线程中不可用。
是否可以与工作人员共享用户的身份验证状态?
// my-firestore-worker.worker.ts
/// <reference lib="webworker" />
import {
collection,
doc,
getDoc,
getDocs,
getFirestore,
query,
} from "@firebase/firestore";
import { initializeApp } from "firebase/app";
const app = initializeApp({
/* none of your business */
});
const firestore = getFirestore(app);
addEventListener("message", async (ev) => {
// This works because the document is allowed for unauthenticated users in our firestore security rules
const appConfig = await getDoc(
doc(
firestore,
`/app/public-config`
)
);
// This gives 'Missing or insufficient permissions' error because of firestore security rules
const projectFilesSnapshot = await getDocs(
query(collection(firestore, `/projects/my-project/tasks`))
);
});
其他观察结果:
fetch
而不是 XMLHttpRequest
构建的,这看起来不错,因为工作人员不支持 XMLHttpRequest
reauthenticateWithCredential
方法,但它需要将密码存储在客户端上,因此这不是一个好的选择。现有技术:
https://davidea.st/articles/firebase-bundle-size/
https://firebase.google.com/docs/auth/web/service-worker-sessions
按照同样的方法,最终在初始化时发现worker内部有firestore拾取授权
firebase/auth
。
/// <reference lib="webworker" />
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { collection, query, where, getDocs, limit } from "firebase/firestore";
import { getAuth } from "firebase/auth";
// Initialize Firebase
const app = initializeApp({
// settings
});
getAuth(app); // <-- this makes everything works
// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);
addEventListener('message', async ({ data }) => {
const q = query(collection(db, "campaigns"), limit(100));
const querySnapshot = await getDocs(q);
const rows = [];
querySnapshot.forEach((doc) => {
rows.push(doc.data());
})
const response = `worker response to ${rows.length}`;
postMessage(response);
});