【问题标题】:Cloud Firestore document .get() and .where() functions not recognizedCloud Firestore 文档 .get() 和 .where() 函数无法识别
【发布时间】:2019-01-22 17:14:09
【问题描述】:

我正在使用 Firebase 身份验证和 Cloud Firestore 构建基于权限的身份验证系统,但在登录时检查用户文档时遇到问题。该应用程序是使用 Angular 6 和 angularfire2 构建的。

这个想法是,一旦用户登录,应用程序将检查是否已为用户创建了用户文档。如果没有,它将创建一个用户文档并使用默认权限和用户信息填充它。

这是我的代码和我尝试过的两个函数:

import { Injectable } from '@angular/core';
import { User } from './../models/user.model';
import { PermissionsService } from './permissions.service';

import { auth } from 'firebase/app';
import { AngularFireAuth } from 'angularfire2/auth';
import {
    AngularFirestore,
    AngularFirestoreDocument,
    AngularFirestoreCollection,
} from 'angularfire2/firestore';

import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

@Injectable({
    providedIn: 'root',
})
export class AuthService {
    usersCollection = null;
    user: Observable<User>;

    constructor(
        private afAuth: AngularFireAuth,
        private db: AngularFirestore,
        private permissionsService: PermissionsService,
    ) {
        this.usersCollection = db.collection('users');
        this.user = this.afAuth.authState.pipe(
            switchMap((user) => {
                if (user) {
                    return this.db
                        .doc<User>(`users/${user.uid}`)
                        .valueChanges();
                } else {
                    return of(null);
                }
            }),
        );
    }

    loginGoogle() {
        const provider = new auth.GoogleAuthProvider();
        return this.oAuthLogin(provider);
    }

    loginFacebook() {
        const provider = new auth.FacebookAuthProvider();
        return this.oAuthLogin(provider);
    }

    loginTwitter() {
        const provider = new auth.TwitterAuthProvider();
        return this.oAuthLogin(provider);
    }

    oAuthLogin(provider) {
        return this.afAuth.auth.signInWithPopup(provider).then((credential) => {
// My first attempt using .where to find a doc with matching email
// This gives an error saying .where() does not exist 
            const docExists = this.usersCollection.where(
                'email',
                '==',
                credential.user.email,
            );
            if (docExists) {
                console.log('User logged in');
            } else {
                console.log('user does not exist');
                this.createUser(credential.user);
            }
//My second attempt using .get() to find a doc with matching uid
//The id of the doc matches the uid of the auth user by design
//This gives an error saying .get() does not exist
            // this.usersCollection
            // .doc(credential.user.uid)
            // .get()
            // .then((docSnapshot) => {
            //  if (docSnapshot.exists) {
            //      console.log('User logged in');
            //  } else {
            //      console.log('user does not exist');
            //      this.createUser(credential.user);
            //  }
            // });
        });
    }

    createUser(user) {
        console.log('creating user');
        const newUser: User = {
            uid: user.uid,
            email: user.email,
            photoURL: user.photoURL,
            displayName: user.displayName,
            roles: {
                member: true,
            },
            permissions: this.permissionsService.memberPermissions,
        };

        this.usersCollection
            .add(newUser)
            .then((docRef) => {
                console.log('added new user');
                newUser.uid = docRef.id;
                docRef.set(newUser);
            })
            .catch((err) => {
                console.log('Error adding user: ' + err);
            });
    }

    logout() {
        this.afAuth.auth.signOut();
        this.user = null;
    }
}

这里是抛出的错误:

zone.js:192 Uncaught TypeError: _this.usersCollection.where 不是函数

zone.js:192 Uncaught TypeError: _this.usersCollection.doc(...).get is 不是函数

我对 firebase 很陌生,尤其是对 Firestore 很陌生(我想每个人都是),我在 angularfire2 或 firebase 的文档中找不到任何可以说明我为什么不能这样做的内容。

请帮助我理解为什么这些函数不被视为有效。

此外,如果您对我如何以更好的方式处理整个身份验证过程有任何提示或 cmet,请随时添加评论。这是我第一次尝试创建这样的身份验证服务。

【问题讨论】:

    标签: javascript firebase firebase-authentication google-cloud-firestore angularfire2


    【解决方案1】:

    // 这给出了一个错误,说 .where() 不存在:

    那是因为.where() 不存在于类型AngularFirestoreCollection 上。你在构造函数中通过this.usersCollection = db.collection('users') 分配它。

    可以这样查询集合:

    const docExists = this.afs.collection&lt;User[]&gt;('users', ref =&gt; ref.where('email', '==', credential.user.email));

    但这不会解决您的问题。在前面的语句中,docExist 也将是一个AngularFirestoreCollection,并且对if (docExists) { 的检查将始终为真。因此,您正在寻找一种基于查询检查文档是否存在的方法:

    private oAuthLogin(provider: any) {
        return this.afAuth.auth
            .signInWithPopup(provider)
            .then(credential => {
                const usersCollection = this.afs.collection<User[]>('users', ref => ref.where('email', '==', credential.user.email));
                const users = usersCollection.snapshotChanges()
                    .pipe(
                        map(actions => {
                            return actions.map(action => {
                                const data = action.payload.doc.data();
                                const id = action.payload.doc.id;
                                return { id, ...data };
                            });
                        }),
                        take(1));
    
                users.subscribe(snap => {
                    if (snap.length === 0) {
                        console.log('user does not exist');
                        this.createUser(credential.user);
    
                    } else {
                        console.log('User logged in');
                    }
                });
            });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-26
      • 2019-07-22
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多