检查用户是不是在 Android 的 Firebase Google 身份验证中首次通过身份验证

Posted

技术标签:

【中文标题】检查用户是不是在 Android 的 Firebase Google 身份验证中首次通过身份验证【英文标题】:Check if user is authenticated for the first time in Firebase Google Authentication in Android检查用户是否在 Android 的 Firebase Google 身份验证中首次通过身份验证 【发布时间】:2017-01-25 18:49:28 【问题描述】:

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

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

【问题讨论】:

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

要检查用户是否是第一次登录,只需在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 属性。【参考方案2】:

从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 错误 - 在此处查看相关帖子:***.com/q/48079683/1145905 但刷新页面后它也会显示精美的介绍屏幕。我不想在刷新后显示花哨的介绍屏幕。 对于我的 Google 登录,这些返回间隔为 2 毫秒,这不可靠。它仅按预期用于电子邮件身份验证。 同意@Anthony。这不适用于 google 登录。【参考方案3】:

根据新版本的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:)

【讨论】:

不工作它总是进入“注册”状态【参考方案4】:

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

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

【讨论】:

【参考方案5】:

将 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")
        
    

【讨论】:

【参考方案6】:

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

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

【讨论】:

【参考方案7】:

在 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
            
        
    

【讨论】:

【参考方案8】:

我使用的解决方法-

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

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

【讨论】:

【参考方案9】:

对于 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

【讨论】:

【参考方案10】:

这可能对您有所帮助并尝试一下:

Correct code location to check Firebase if a user has been created already?

【讨论】:

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

首先检查 - 如果当前用户 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;

【讨论】:

以上是关于检查用户是不是在 Android 的 Firebase Google 身份验证中首次通过身份验证的主要内容,如果未能解决你的问题,请参考以下文章

检查Android代码中是不是存在用户名

哪个是检查用户位置(android 应用程序)是不是在多边形内的更好方法

Android Google Map如何检查用户是不是在标记矩形区域

检查Android中的用户是不是已经授予权限

检查用户是不是在 Android 的 Firebase Google 身份验证中首次通过身份验证

我如何检查用户是不是真的在他的手机上启用了 android 中的 gps 位置