如何防止 Firebase 一遍又一遍地创建同一个用户?

Posted

技术标签:

【中文标题】如何防止 Firebase 一遍又一遍地创建同一个用户?【英文标题】:How to prevent Firebase from creating the same user over and over again? 【发布时间】:2019-07-05 00:05:04 【问题描述】:

我目前正在 Ionic 4 框架(以 Firebase 作为后端)中开发一个事件应用程序,在 Cloud Firestore 数据库上创建用户时遇到了问题。每当我使用 Google 或 Facebook 登录时,Firebase 都会在数据库中创建一个新条目,尽管我使用同一用户登录。 如果当前 user_id 已存在于数据库中,我尝试执行检查,但我的代码似乎有问题。如何修复它,以便我的代码正确检查当前用户是否已存在于数据库中?

目前,我在我的登录组件中检查用户是否已存在于 Cloud Firestore 数据库中。我已经尝试在我的用户服务中直接在 createUser() 函数中构建一个检查。但行为完全一样。

以下代码显示了我的登录组件中的功能:

googleLogin() 
    if (this.authService.googleLogin()) 
    this.authService.getAuthState().subscribe(user => 
        if (user) 
          // User is signed in.
          console.log("Logged In ", user.email);
          this.userId = user.uid;
          this.user.name = user.displayName;

          this.afs.firestore.doc('user/' + user.uid).get()
          .then(docSnapshot => 
            if (docSnapshot.exists) 
              console.log("user already exists");
             else 
              this.userservice.createUser(this.user);
            
          );
         else 
          console.log("Not Logged In");
          this.userId = undefined;
        
      
    );

以下代码显示了我的用户服务中的功能:

createUser(user: any): Promise<any> 
      return this.afs.collection("user").add(
        blockPushMessages: user.blockPushMessages,
        email: user.email,
        isAnonymous: user.isAnonymous,
        name: user.name,
        partyLevel: user.partyLevel,
        aliasName: user.aliasName,
        dateOfBirth: user.dateOfBirth,
        gender: user.gender,
        homeTown: user.homeTown,
        personImage_id: user.personImage_id,
        registrationDate: user.registrationDate,
        relationshipStatus: user.relationshipStatus,
        school: user.school
      );
  

以下代码显示了我的身份验证服务中的谷歌登录功能:

googleLogin() 
    if (this.platform.is("cordova")) 
      this.nativeGoogleLogin();
     else 
      this.webGoogleLogin();
    
    return true;
  

async nativeGoogleLogin(): Promise<firebase.User> 
    try 
      const gplusUser = await this.gplus.login(
        webClientId:
          "**********",
        offline: true,
        scopes: "profile email"
       );
       return await this.afAuth.auth.signInWithCredential(
        firebase.auth.GoogleAuthProvider.credential(gplusUser.idToken)
      );
     catch (err) 
      console.log(err);
    
  

 async webGoogleLogin(): Promise<void> 
    try 
      const provider = new firebase.auth.GoogleAuthProvider();
      const credential = await this.afAuth.auth.signInWithPopup(provider);
     catch (err) 
      console.log(err);
    
  

我希望代码检查当前用户是否已存在于我的 Cloud Firestore 数据库中。目前的实际结果是,代码忽略了检查,只是在数据库上创建了一个新用户,即使我使用同一个用户登录。

如果有人知道我的代码有什么问题,请告诉我。我会很感激的!

【问题讨论】:

【参考方案1】:

好像你在比较 uid,你确定 uid 是你后端的用户 ID 吗?

【讨论】:

非常感谢!那实际上是我的错误。我更改了我的 createUser() 函数以使用 user.uid 而不是随机生成的 Id 创建文档,现在它可以工作了!我将更新我的帖子以展示我的工作解决方案。【参考方案2】:

我实际上是在将 uid 与数据库中随机生成的文档 ID 进行比较。我现在通过给我的用户对象一个 internal_id 并使用 uid 而不是随机生成的文档 ID 在数据库上创建用户文档来修复代码。这是可行的解决方案:

来自我的用户服务的代码:

createUser(user: any): Promise<any> 
      return this.afs.collection("user").doc(user.internal_id).set(
        internal_id: user.internal_id,
        blockPushMessages: user.blockPushMessages,
        email: user.email,
        isAnonymous: user.isAnonymous,
        name: user.name,
        partyLevel: user.partyLevel,
        aliasName: user.aliasName,
        dateOfBirth: user.dateOfBirth,
        gender: user.gender,
        homeTown: user.homeTown,
        personImage_id: user.personImage_id,
        registrationDate: user.registrationDate,
        relationshipStatus: user.relationshipStatus,
        school: user.school
      );
  

来自我的登录组件的代码:

googleLogin() 
    if (this.authService.googleLogin()) 
    this.authService.getAuthState().subscribe(user => 
        if (user) 
          // User is signed in.
          console.log("Logged In ", user.email);
          this.user.internal_id = user.uid;
          this.internal_id = user.uid;
          this.user.name = user.displayName;

          this.afs.firestore.doc('user/' + this.internal_id).get()
          .then(docSnapshot => 
            if (docSnapshot.exists) 
              console.log("user already exists");
             else 
              this.userservice.createUser(this.user);
            
          );
         else 
          console.log("Not Logged In");
          this.userId = undefined;
        
      
    );

【讨论】:

以上是关于如何防止 Firebase 一遍又一遍地创建同一个用户?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止innerHtml表一遍又一遍地重复自己?

一遍又一遍地创建 PHP MVC 控制器

为啥在反应的“useState”钩子中一遍又一遍地设置初始状态

为啥这不会一遍又一遍地返回一个新值?爪哇

命名管道未按预期工作。一遍又一遍地阅读相同的消息

如何装饰一个类的所有函数而不为每个方法一遍又一遍地键入它? [复制]