【问题标题】:AngularFire: How To Access Firestore Only When AuthenticatedAngularFire:如何仅在经过身份验证后访问 Firestore
【发布时间】:2021-08-24 23:18:49
【问题描述】:

我想使用 AngularFire 将 Firestore 访问权限限制为经过身份验证的用户,但出现以下错误:

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 规则

如果读取规则更改为仅“允许读取”;上面的应用程序按预期工作。

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

但是 - 原始 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

我的代码在this GitHub repository 中可用。

【问题讨论】:

    标签: firebase-authentication angularfire2


    【解决方案1】:

    在你的构造函数中它应该看起来更像这样

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

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

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-29
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多