AngularFire:如何仅在经过身份验证时访问Firestore



我想将Firestore访问限制为使用AngularFire进行身份验证的用户,但收到以下错误:

core.js:6456 ERROR FirebaseError: Missing or insufficient permissions.
at new e (prebuilt-109c6673-0f51e182.js:188)
at prebuilt-109c6673-0f51e182.js:10416
at prebuilt-109c6673-0f51e182.js:10414
at e.onMessage (prebuilt-109c6673-0f51e182.js:10403)
at prebuilt-109c6673-0f51e182.js:10356
at prebuilt-109c6673-0f51e182.js:10387
at prebuilt-109c6673-0f51e182.js:15194
at ZoneDelegate.invoke (zone.js:372)
at Zone.run (zone.js:134)
at zone.js:1276

我创建了一个非常基本的测试应用程序来测试这一点。

app.component.html

<ng-container *ngIf="auth.user | async as user; else showLogin">
<ul>
<li *ngFor="let profile of profiles | async">{{profile.DisplayName}}</li>
</ul>
</ng-container>
<ng-template #showLogin>
<p>You must sign in to continue.</p>
<button (click)="signIn()"> SIGN IN </button>
</ng-template>

app.component.ts

import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';
import firebase from 'firebase/app';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'test-auth';
profiles: Observable<any[]>;
constructor (
public auth: AngularFireAuth,
private firestore: AngularFirestore) {
this.profiles = firestore.collection('UserProfiles').valueChanges();
}
signIn(): void {
this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
signOut(): void {
this.auth.signOut();
}
}

我的Firestore规则

如果读取规则被改变为仅"0";允许读取"上面的应用程序按预期工作。

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
}

我的版本

Angular CLI: 12.0.3
Node: 14.17.0
Package Manager: npm 7.13.0
OS: linux x64
Angular: 12.0.3
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1200.3
@angular-devkit/build-angular   12.0.3
@angular-devkit/core            12.0.3
@angular-devkit/schematics      12.0.3
@angular/fire                   6.1.5
@schematics/angular             12.0.3
rxjs                            6.6.7
typescript                      4.2.4
$ firebase --version
9.12.1

然而,raw Firebase如预期的那样工作

使用以下代码,我将此问题隔离为(1(AngularFire中的一个错误(?(或(2(我无法在之前的评论中提供的代码中正确实现AngularFire。

app.component.ts

import { Component, OnDestroy, OnInit } from '@angular/core';
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';
export interface ProfileModel {
Id: string,
DisplayName: string
}
export interface CurrentUser {
uid: string;
name?: string;
email?: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnDestroy, OnInit {
title = 'test-auth';
currentUser: CurrentUser | null = null;
profilesArray: ProfileModel[] = [];
fb: firebase.app.App;
fs: firebase.firestore.Firestore;
profilesCollection: firebase.firestore.CollectionReference<firebase.firestore.DocumentData>;
unsubscribe?: firebase.Unsubscribe;
constructor () {
this.fb = firebase.initializeApp({
apiKey: "OMITTED",
authDomain: "angularfiretestapp.firebaseapp.com",
databaseURL: "https://angularfiretestapp.firebaseio.com",
projectId: "angularfiretestapp",
storageBucket: "angularfiretestapp.appspot.com",
messagingSenderId: "OMITTED",
appId: "OMITTED",
measurementId: "OMITTED"  
});
this.fs = firebase.firestore();
this.profilesCollection = this.fs.collection('UserProfiles');
}
ngOnDestroy():void {
if (this.unsubscribe) {
this.unsubscribe();
}
}
ngOnInit():void {
this.unsubscribe = this.fb.auth().onAuthStateChanged(authUser => {
if (authUser) {
this.currentUser = {
uid: authUser.uid,
name: authUser.displayName ? authUser.displayName : '',
email: authUser.email ? authUser.email : ''
};
this.profilesArray = [];
this.profilesCollection.get().then(qSnap => {
qSnap.forEach(doc => {
this.profilesArray.push({
Id: doc.id,
DisplayName: doc.get('DisplayName')
});
});
});
} else {
this.currentUser = null;
}  
});
}
signIn(): void {
this.fb.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
signOut(): void {
this.fb.auth().signOut();
}
}

app.component.html

<ng-container *ngIf="currentUser; else showLogin">
<p>Here are some profiles:</p>
<ul>
<li *ngFor="let profile of profilesArray">{{profile.DisplayName}}</li>
</ul>
<button (click)="signOut()"> SIGN OUT </button>
</ng-container>
<ng-template #showLogin>
<p>You must sign in to continue.</p>
<button (click)="signIn()"> SIGN IN </button>
</ng-template>

张贴在其他地方

第2838期在GitHub上提交。

也发布在Reddit上。

我的代码在这个GitHub存储库中可用。

在构造函数中,它应该更像这个

auth.onAuthStateChanged((user) => {
if (user && user.emailVerified) {
this.profiles = firestore.collection('UserProfiles').valueChanges();
} else {
signIn();
}
});

如果它仍然抛出异常,您可以尝试将firebase降级为8.3.0。

最新更新