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();
}
});
我的用例是,我有一个网络应用程序,我在其中收听 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();
}
});