Firebase:连接到同一个 Firestore 数据库的经过身份验证的客户端和来宾客户端

Firebase: authenticated and guest clients connecting to same Firestore Database

我的用例是,我有一个网络应用程序,我在其中收听 Firestore 集合。其中一个集合供 public 用户使用,其中匿名身份验证就足够了。第二个集合用于登录用户,因此我在此之后实现了自定义令牌身份验证。 https://firebase.google.com/docs/auth/web/custom-auth。 用户登录后,我们启动 Web Worker 来初始化应用程序并监听 Firestore。

我的问题是,当用户登录时,第二个订阅(经过身份验证的订阅)有效,但如果我尝试转到 public 页面,我不需要身份验证令牌,从相同的选项卡,我收到此错误。

Uncaught (in promise) FirebaseError: Missing or insufficient permissions.
    at new Ur (prebuilt.js:184:9)
    at prebuilt.js:10612:34
    at br.<anonymous> (prebuilt.js:10564:21)
    at Bt (eventtarget.js:351:23)
    at qt (eventtarget.js:481:26)
    at Ir.wa (webchannelbasetransport.js:369:17)
    at Ke (webchannelbase.js:2258:25)
    at Fe (channelrequest.js:951:12)
    at Ne.N.Ia (channelrequest.js:743:10)
    at Ne.N.gb (channelrequest.js:603:10)

两个订阅使用相同的 firebase 应用程序,相同的配置。

更多信息:

这些是规则

function isSignedIn(){
  return request.auth != null;
}

function isDocumentOwner(docid) {
  // checks if user id is the same as the document id
  return isSignedIn() && request.auth.uid == docid;
}
//this collection can be accessed for guest/anonymous users
match /guests/{uid} {
  allow read, write: if isDocumentOwner(uid);
}
//this collection in only accessible for logged in users(JWT token)
match /users/{uid} {
  allow read, write: if isDocumentOwner(uid);
}

这是初始化代码

访客页面:

const app = initializeApp(firebaseConfig);
db = getFirestore(app);
auth = getAuth();
signInAnonymously(auth);

onAuthStateChanged(auth, (loginUser) => {
  if (loginUser) {
    user = loginUser;
  } else {
    unsubscribe();
  }
});

登录页面:

const app = initializeApp(firebaseConfig);
db = getFirestore(app);
auth = getAuth();
signInWithCustomToken(auth, customToken);

onAuthStateChanged(auth, (loginUser) => {
  if (loginUser) {
    user = loginUser;
  } else {
    unsubscribe();
  }
});

我明白了。我从两个地方连接到同一个 firebase 应用程序。第一个来自 Web Worker,具有自定义令牌身份验证,第二个来自具有匿名登录的同一浏览器的不同选项卡。当第二个连接尝试启动与匿名身份验证的连接时,它不起作用,因为该应用程序已经使用自定义令牌启动,未满足规则的这一部分,

request.auth.uid == docid

request.auth.uid是登录者的。

修复:

我必须创建另一个应用程序和一组用于登录用户的配置。然后,我在初始化和授权应用程序时必须提供一个应用程序名称。

const app = initializeApp(firebaseConfig, 'new-app');
db = getFirestore(app);
auth = getAuth(app);
signInWithCustomToken(auth, customToken);

onAuthStateChanged(auth, (loginUser) => {
  if (loginUser) {
    user = loginUser;
  } else {
    unsubscribe();
  }
});