typescript - Firebase 对 .doc().get() 的权限不足
问题描述
我正在尝试在我的应用程序中对用户进行身份验证。我有一个登录屏幕,它需要一个电子邮件和密码,然后运行它:
login2(email: string, password: string): Observable<any> {
const signInObs: Observable<UserCredential> = from(this.fAuth.signInWithEmailAndPassword(email, password));
return signInObs.pipe(take(1), catchError(this.handleError), mergeMap((result: UserCredential) => {
console.log(`done this ONE... ${result.user.uid}`);
return this.firestore.collection('users').doc(result.user.uid).get().pipe(catchError(this.handleError), mergeMap((doc: DocumentSnapshot<any>) => {
console.log(`done this two... ${doc.data().name}`);
return result.user.getIdTokenResult(true).then((token: IdTokenResult) => {
// authenticate the user in the code
console.log(`done this three.. ${token.claims.admin}`);
this.handleAuthentication(
result.user.email,
result.user.uid,
doc.data().name,
token.claims.admin,
token.token
);
}).catch(error => {
throw new Error(error);
});
}));
}));
}
但是旧的ERROR FirebaseError: Missing or insufficient permissions.
错误发生在 this.firebase.collection('users').doc(result.user.uid).get()
零件上。没有那个部分,这一切都很好 - 即它登录,给我一个令牌等等。一切正常,只是它不允许我访问该用户记录......
我的数据库中的规则是:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// match logged in user doc in users collection
match /users/{userId} {
allow create: if request.auth.uid != null;
allow read: if request.auth != null && request.auth.uid == userId;
}
// match docs in the users collection
match /users/{userId} {
allow read, write: if request.auth.uid != null;
}
}
}
参考建议可能是 FireAuth 和 Firestore 模块无法正确通信的回复,这就是app.module
外观。这些都是 app.module 中对 angular fire 模块的引用。
import { environment } from 'src/environments/environment';
import { AngularFireModule } from '@angular/fire';
import { AngularFireFunctions } from '@angular/fire/functions';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { AngularFirestoreModule } from '@angular/fire/firestore';
@NgModule({
declarations: [
// just components
],
imports: [
// other imports
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFirestoreModule,
AngularFireAuthModule
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptorService, multi: true},
AuthenticationService,
AngularFireFunctions
],
bootstrap: [AppComponent]
})
export class AppModule { }
以及身份验证服务中的构造函数:
constructor(private fAuth: AngularFireAuth,
private firestore: AngularFirestore,
private router: Router) {
}
我已经尝试通过模拟器运行 id,它似乎应该可以工作。我已经从登录中记录了用户 ID,它与它应该寻找的文档名称相同。
这一切似乎都应该起作用,但事实并非如此。我已经阅读了一堆教程,但没有一个做任何巨大的不同 - 教程之间的差异是不一致的。
我认识到代码在编写方式上并不完美,但希望首先使其发挥作用。
我在数据库中的数据结构如下所示:
文档的 ID 是相关人员的用户 ID,我仔细检查了它们都是正确的。
仔细检查它是否有效,否则如果我允许通用读写,那么一切都会正常工作......只有当这些规则出现时它们才不起作用。
解决方案
您必须指定要匹配的文档,在这种情况下,它是所有文档(递归)。这是规则:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// match logged in user doc in users collection
match /users/{userId}/{documents=**} {
allow create: if request.auth.uid != null;
allow read: if request.auth.uid == userId;
}
// match docs in the users collection
match /users/{userId}/{documents=**} {
allow read, write: if request.auth.uid != null;
}
}
}
评论后编辑:根据https://firebase.google.com/docs/firestore/security/rules-structure#version-2 “在安全规则的第2版中,递归通配符匹配零个或多个路径项。匹配/ city/{city}/{document=**} 匹配任何子集合中的文档以及城市集合中的文档。" . 我猜上面的代码解决了子集合问题。如果您仍然遇到问题,请分享您的数据结构,以便人们可以更好地提供帮助。
第二次编辑:我猜这个问题是因为 request.auth 是空的。如果有空指针,Firebase 会抛出错误。所以在 request.auth.uid 之前,您必须检查 request.auth 是否为空。像那样:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// match logged in user doc in users collection
match /users/{userId}/{documents=**} {
allow create: if request.auth != null && request.auth.uid != null;
allow read: if request.auth != null && request.auth.uid == userId;
}
// match docs in the users collection
match /users/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid != null;
}
}
}
第三次编辑:我昨天遇到了同样的问题(规则很好,当所有规则都设置为 true 时它可以工作)但奇怪的是它只发生在移动设备上。我在 GitHub 上搜索后发现了这个问题:https ://github.com/angular/angularfire/issues/2838 。该问题是由 Firebase 版本引起的。我的版本是8.6.2,所以我降级到8.6.1,问题就解决了。您可以通过以下方式降级:
npm install firebase@8.6.1
我认为这对 Firebase 来说是一个非常严重的问题,它阻碍了人们使用 Firebase 后端开发和维护项目。我希望这也能解决你的问题。
推荐阅读
- go - 创建实现接口的结构实例的函数
- scala - Sequential execution of IO from Future
- privacy - Determining default privacy settings
- android - canvas.drawPosText is deprecated since API 16. What's the replacement?
- xml - 管理 xmlagg 的空值
- html - Re-order cards in different columns on smaller screen sizes
- javascript - 无法让 JavaScript 连接到 PostgresSql
- ros - Gazebo shows more robots than robot launched number
- javascript - How to add to each object in an array a key-pair value based on each objects id?
- reactjs - change "css" (in one component) based on some condition in other component? (REACT)