与 Web Worker 共享 Firebase 身份验证状态,以进行需要身份验证的 Firestore 查询

问题描述 投票:0回答:1

我们正在测试使用 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`))
  );
});

其他观察结果:

  • firebase v9 JavaScript SDK 是使用
    fetch
    而不是
    XMLHttpRequest
    构建的,这看起来不错,因为工作人员不支持
    XMLHttpRequest
  • Firebase auth 有一个
    reauthenticateWithCredential
    方法,但它需要将密码存储在客户端上,因此这不是一个好的选择。

现有技术:

https://davidea.st/articles/firebase-bundle-size/

https://firebase.google.com/docs/auth/web/service-worker-sessions

https://firebase.google.com/docs/cloud-messaging/js/receive

javascript firebase google-cloud-firestore service-worker web-worker
1个回答
0
投票

按照同样的方法,最终在初始化时发现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);
});

© www.soinside.com 2019 - 2024. All rights reserved.