【问题标题】:Check if user is authenticated for the first time in Firebase Google Authentication in Android检查用户是否在 Android 的 Firebase Google 身份验证中首次通过身份验证
【发布时间】:2023-03-04 13:02:01
【问题描述】:

我在 Android 应用程序中使用 Firebase 身份验证,并且我使用 Google 帐户身份验证作为登录应用程序的选项。

我如何知道用户是否是第一次登录应用程序?

【问题讨论】:

  • 那么您想使用 Firebase Auth 检索所有用户的列表吗?
  • 是的,这正是我要找的
  • 很遗憾,您不能以这种方式使用 Firebase 身份验证。您必须遵循@NarenderReddy 所说的内容 - 每次用户首次登录时,您都需要使用 Firebase 数据库(或您的首选存储方法)存储某种条目以及您想要跟踪的信息。然后,您可以使用该数据库位置来获取所有用户的列表。
  • 好的,正如您所知,每次用户在我的应用程序中注册时,我都会为他存储一个 ID,但问题是当用户签名时我无法对数据库进行查询在中,我只找到了带有 dataSnapshot childEventListener 的示例,这就是我在这里问另一个问题的原因:stackoverflow.com/questions/39552168/…

标签: android firebase firebase-authentication


【解决方案1】:

【讨论】:

  • @adityashrivastava 您的 SO 问题是指用户设置的 Firebase 数据库(实时数据库)。希望能够仅使用 Firebase(身份验证)来解决它
【解决方案2】:

将 Firebase Auth 与 Firestore 结合使用时的解决方案

Firestore 数据库的根架构如下所示

使用 Firebase 身份验证 currentUser.uid 为每个用户创建一个根文档。首次创建用户后,首先将名为 registered_at 的字段添加到根文档,然后根据您的用例将您的特定集合添加到根文档。

登录或登录时,您可以检查具有registered_at 字段的文档是否已存在。如果它还不存在,那么您可以将用户视为新用户(假设用户以后不能删除或更改registered_at字段)

import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore

fun rootDocument(): DocumentReference? = rootPath()?.let {
    return fireStore().document(it)
}

fun rootPath(): String? {
    val loggedInUser = loggedInUser()
    if (loggedInUser != null) {
        return "users/${loggedInUser.uid}"
    }
    return null
}

fun fireStore() = FirebaseFirestore.getInstance()

fun createWriteBatch() = fireStore().batch()

fun loggedInUser() = fireAuth().currentUser

fun fireAuth(): FirebaseAuth = FirebaseAuth.getInstance()

fun afterSignIn() {

    val rootDocument = rootDocument()
            ?: throw IllegalStateException("root document not found")

    rootDocument.get().addOnCompleteListener {
        val isNewUser = it.result.exists().not()

        if (isNewUser) {
            val batch = createWriteBatch()

            batch.set(rootDocument, HashMap<Any, Any>().apply {
                put("registered_at", System.currentTimeMillis())
            })

            batch.commit().addOnCompleteListener {
                println("this is a new user")
            }

        } else {
            println("this is not a new user")
        }
    }
}

【讨论】:

    【解决方案3】:

    虽然我完全同意最正确的方法(鉴于无法向身份验证用户表添加新字段)是为用户创建新路径并将信息存储在那里,但我不想在之后提出额外的请求登录以进行此检查(我正在使用 Firestore 并且请求 = 金钱)。

    我需要进行第一次登录检查以提示输入用户名(因为显示名称是从 Facebook/Google 提取的,如果这是他们的第一次登录,我想提供覆盖选项)。我最终做的是使用 photoURL 属性作为标志来确定这是否是他们的第一次。这并不理想,但也许想要节省请求的人可以将其用作解决方法。这对 Firebase 来说没什么大不了的,但对于 Firestore 来说,您的计划成本更高

    【讨论】:

      【解决方案4】:

      从 11.6.0 版本开始,我们可以使用 AdditionalUserInfo.isNewUser()

      https://firebase.google.com/docs/reference/android/com/google/firebase/auth/AdditionalUserInfo

      【讨论】:

        【解决方案5】:

        要检查用户是否是第一次登录,只需在OnCompleteListener.onComplete 回调中调用AdditionalUserInfo.isNewUser() 方法即可。

        下面的示例代码,一定要检查是否为空。

        OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        boolean isNew = task.getResult().getAdditionalUserInfo().isNewUser();
                        Log.d("MyTAG", "onComplete: " + (isNew ? "new user" : "old user"));
                    }
                }
            };
        

        查看文档以获取更多参考 AdditionalUserInfo

        【讨论】:

        • 它不起作用,我在 onCreate() 下声明了它,但它从未运行过
        • @Sandeep 您能否更具体地说明什么不起作用。一些代码 sn-ps 也会很有帮助
        • @erict 在颤振中怎么做?
        • @puzzled 在 Flutter 中,您可以从 AuthResult 中获取 result.additionalUserInfo.isNewUser 属性。
        【解决方案6】:

        Firebase-ui docs,您可以检查上次登录时间戳与创建时间戳,如下所示:

        FirebaseUserMetadata metadata = auth.getCurrentUser().getMetadata();
        if (metadata.getCreationTimestamp() == metadata.getLastSignInTimestamp()) {
            // The user is new, show them a fancy intro screen!
        } else {
            // This is an existing user, show them a welcome back screen.
        }
        

        【讨论】:

        • 这可能是 Firebase 错误 - 在此处查看相关帖子:stackoverflow.com/q/48079683/1145905
        • 但刷新页面后它也会显示精美的介绍屏幕。我不想在刷新后显示花哨的介绍屏幕。
        • 对于我的 Google 登录,这些返回间隔为 2 毫秒,这不可靠。它仅按预期用于电子邮件身份验证。
        • 同意@Anthony。这不适用于谷歌登录。
        【解决方案7】:

        根据新版本的Firebase auth (16.0.1) AuthResult 类有一个成员函数,结果为真或假(用户是新用户)。 假设在范围内定义了“凭据”(它是 google 凭据)。一个例子如下所示: `

        private FirebaseAuth mAuth;
        
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestIdToken(getString(R.string.default_web_client_id))
                    .requestEmail()
                    .build();
        
        mAuth = FirebaseAuth.getInstance();
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        GoogleSignInAccount acct = task.getResult(ApiException.class);
        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        
        mAuth.signInWithCredential(credential)
                    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            if (task.isSuccessful()) {
                                Log.d(TAG, "linkWithCredential:success");
        
        
                                boolean newuser = task.getResult().getAdditionalUserInfo().isNewUser();
        
        
        
                                if(newuser){
        
                                     //Do Stuffs for new user
        
                                 }else{
        
                                    //Continue with Sign up 
                                }
        
                            } else {
        
                                Toast.makeText(MyClass.this, "Authentication failed.",
                                        Toast.LENGTH_SHORT).show();
        
                            }
        
        
                    });
        

        感谢 firebase:)

        【讨论】:

        • 不工作它总是进入“注册”状态
        【解决方案8】:

        在 Firebase 用户界面、JAVA 中:

         @Override
            protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                Intent i;
        
        
                if (requestCode == RC_SIGN_IN) {
                    IdpResponse response = IdpResponse.fromResultIntent(data);
        
                    if (resultCode == RESULT_OK) {
        
        
                        if(response.isNewUser()){
                        Log.d(TAG, "onActivityResult: isNewUser "+response.isNewUser());
        } else {
        
                        // Successfully signed in
                        }
        
                        // ...
                    } else {
        
        
        
        //               handle error
                    }
                }
            }
        
        

        【讨论】:

          【解决方案9】:

          首先检查 - 如果当前用户 uid 与您的文档 id 匹配,那么它是旧用户,否则它是新用户

          例子

          private boolean isUserMatch(String currentUserId) {
              firestore.collection(COLLECTION_USER).get().addOnCompleteListener(new OnCompleteListener< QuerySnapshot >() {
                  @Override
                  public void onComplete(@NonNull @NotNull Task< QuerySnapshot > task) {
                      if (task.isSuccessful()) {
                          for (QueryDocumentSnapshot documentSnapshot : task.getResult()) {
                              if (currentUserId.equals(documentSnapshot.getId())) {
                                  return;
                              }
                          }
                      }
                  }
              }).addOnFailureListener(new OnFailureListener() {
                  @Override
                  public void onFailure(@NonNull @NotNull Exception e) {
                      Log.e(TAG, "onFailure: ", e.getCause());
                  }
              });
              return false;
          }
          

          【讨论】:

            【解决方案10】:

            我使用的解决方法-

            1. 在 Firestore 中创建了一个名为“Users”的集合。
            2. 每当有人登录时,获取其 uid
            3. 在“用户”中搜索该 uid。确保将“用户”文档命名为用户的 UID。
            4. 如果文档存在,那么它是新用户,如果不存在
            5. 然后将该特定用户的文档添加到该集合“用户”中。

            Trick Used - 使用 UID 来解决这个问题。 谢谢,如果有帮助请点赞

            【讨论】:

              【解决方案11】:

              对于 Web,版本 9.0(模块化):

              您需要导入“getAdditionalUserInfo”并这样调用它:

              signInWithPopup(firebaseAuth, provider)
                .then((result) => {
                  const details = getAdditionalUserInfo(result)
                  console.log(details)
                })
                .catch((error) => {
                  console.log(error);
                });
              

              返回的详细信息包括一个“isNewUser”布尔属性。

              Details on GitHub from August 2021

              【讨论】:

                猜你喜欢
                • 2021-05-01
                • 1970-01-01
                • 2021-09-22
                • 1970-01-01
                • 2019-12-29
                • 2018-12-28
                • 1970-01-01
                • 2016-09-26
                相关资源
                最近更新 更多