首页 > 解决方案 > 使用 firebase google 退出后,我再次登录。我保留在数据库中的所有数据都被删除

问题描述

我希望它使用 google 登录,以在我的应用程序中保留用户最喜欢的单词。当用户退出应用程序时,用户会回到使用 google 的登录页面。并且所有用户喜欢的词都被删除。我该如何解决这个问题下面我显示删除的部分?

class SignInActivity : AppCompatActivity() {

    companion object {
        private const val RC_SIGN_IN = 120
    }

    private lateinit var mAuth: FirebaseAuth
    private lateinit var googleSignInClient: GoogleSignInClient

    private lateinit var database: DatabaseReference


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_in)

        val sign_in_btn : Button = findViewById(R.id.sign_in_btn)

        // Configure Google Sign In
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build()
        googleSignInClient = GoogleSignIn.getClient(this, gso)


        database = Firebase.database.reference

        //Firebase Auth instance
        mAuth = FirebaseAuth.getInstance()

        sign_in_btn.setOnClickListener {
            signIn()
        }
    }

    private fun writeNewUser(userId: String, name: String, email: String) {
        val user = Users(userId, name, email)

        database.child("users").child(userId).setValue(user)
    }

    private fun signIn() {
        val signInIntent = googleSignInClient.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            val exception = task.exception

            if(task.isSuccessful){
                try {
                    // Google Sign In was successful, authenticate with Firebase
                    val account = task.getResult(ApiException::class.java)!!
                    Log.d(ContentValues.TAG, "firebaseAuthWithGoogle:" + account.id)
                    firebaseAuthWithGoogle(account.idToken!!)
                } catch (e: ApiException) {
                    // Google Sign In failed, update UI appropriately
                    Log.w(ContentValues.TAG, "Google sign in failed", e)
                }
            }else{
                Log.w(ContentValues.TAG, exception.toString())
            }

        }
    }
    private fun firebaseAuthWithGoogle(idToken: String) {
        val credential = GoogleAuthProvider.getCredential(idToken, null)
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {

                    val user = mAuth.currentUser
                    writeNewUser(user?.uid.toString(), user?.displayName.toString(),
                        user?.email.toString()
                    )
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(ContentValues.TAG, "signInWithCredential:success")

                    val intent = Intent(this, DashboardActivity::class.java)
                    startActivity(intent)
                    finish()
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(ContentValues.TAG, "signInWithCredential:failure", task.exception) }
            }
    }
}

And my SignOut function

     sign_out_btn.setOnClickListener {
            mAuth.signOut()
            val intent = Intent(this,SignInActivity::class.java)
            startActivity(intent)
            finish()
        }

在此处输入图像描述

标签: androidfirebasekotlinfirebase-realtime-databasefirebase-authentication

解决方案


你总是把所有东西都抹掉,因为当你使用 Google 成功执行 Firebase 身份验证时,你总是调用 writeNewUser() 方法,该方法实际上使用以下代码行在数据库中执行写入操作:

database.child("users").child(userId).setValue(user)

所以这实际上意味着你总是把对象写user在现有的对象上。令人惊讶的是,这不是你想要的。为了解决这个问题,您需要在执行新的写入操作之前检查用户是否已经存在于数据库中。所以请检查我从以下帖子中的答案:

因此,如果用户数据尚不存在,您只需要写入用户数据。


推荐阅读