安卓基于 FirebaseAuth 实现 google 登录

发布于:2025-07-15 ⋅ 阅读:(19) ⋅ 点赞:(0)

安卓基于 FirebaseAuth 实现 google 登录

本文首发地址 https://h89.cn/archives/414.html

在 Android 应用中基于 Firebase Authentication 实现 Google 登录是一个非常常见的需求,因为它简化了用户认证流程,并利用了 Google 强大的身份验证基础设施。下面我将详细介绍整个实现过程。


1. 前期准备

1.1 创建 Firebase 项目

  1. 访问 Firebase 控制台: 访问 Firebase Console
  2. 创建新项目或选择现有项目: 如果你还没有 Firebase 项目,点击“添加项目”并按照向导创建。如果你已有项目,选择它。

1.2 将 Android 应用连接到 Firebase

  1. 在 Firebase 控制台的项目概览页面,点击 “将应用添加到 Firebase”,然后选择 “Android” 图标。

  2. 输入 Android 包名: 输入你的 Android 应用的包名(例如:com.yourcompany.yourapp)。这个包名必须与你 build.gradle 文件中的 applicationId 一致。

  3. 输入 SHA-1 密钥: SHA-1 指纹用于验证你的应用与 Firebase 项目的关联。

    • 获取 SHA-1: 在 Android Studio 中,打开 Gradle 面板(通常在右侧),展开你的项目 -> Tasks -> android,双击 signingReport。你会在 Run 窗口中看到 SHA-1 指纹。
    • 将 SHA-1 复制并粘贴到 Firebase 控制台。
  4. 下载 google-services.json 文件: 按照 Firebase 控制台的指示下载 google-services.json 文件,并将其放置到你的 Android 项目的 app/ 目录下。

  5. 添加 Firebase SDK: 按照指示在你的 build.gradle 文件中添加必要的 Firebase SDK 依赖项。

    • 项目级别的 build.gradle (<project>/build.gradle):

      buildscript {
          repositories {
              google()
              mavenCentral()
          }
          dependencies {
              classpath 'com.android.tools.build:gradle:8.x.x' // 根据你的Android Studio版本调整
              classpath 'com.google.gms:google-services:4.x.x' // 最新版本
          }
      }
      
      allprojects {
          repositories {
              google()
              mavenCentral()
          }
      }
      
    • 应用级别的 build.gradle (<project>/app/build.gradle):

      plugins {
          id 'com.android.application'
          id 'com.google.gms.google-services' // 添加这一行
      }
      
      android {
          // ...
      }
      
      dependencies {
          // ...
          implementation(platform("com.google.firebase:firebase-bom:33.x.x")) // 最新版本
          implementation("com.google.firebase:firebase-auth")
          implementation("com.google.android.gms:play-services-auth:21.x.x") // Google Sign-In SDK
      }
      
    • 同步项目: 修改完 build.gradle 文件后,同步你的 Android 项目。

1.3 在 Firebase 控制台中启用 Google 登录

  1. 在 Firebase 控制台,点击左侧菜单的 “Authentication”
  2. 选择 “Sign-in method” 标签页。
  3. 找到 “Google” 提供商,点击它。
  4. 启用 Google 登录,然后点击 “保存”
    • 重要提示: 在这里,你需要确保已经有一个“Web 客户端(Web application)”类型的 OAuth 2.0 客户端 ID。Firebase 会自动为你的项目生成一个,但如果你在 Google Cloud Console 中手动创建过项目,可能需要检查。这个 Web 客户端 ID 是用于后端服务器与 Google 认证服务通信的,不是你的 Android 客户端 ID。

2. 在 Android 应用中实现 Google 登录

2.1 初始化 GoogleSignInClient

在你的 Activity 或 Fragment 中,首先需要初始化 GoogleSignInClient 对象。这个对象用于启动 Google 登录流程。

// Kotlin
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth

class MainActivity : AppCompatActivity() {

    private lateinit var googleSignInClient: GoogleSignInClient
    private lateinit var firebaseAuth: FirebaseAuth

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

        // 配置 Google Sign In 以请求用户的 ID、电子邮件地址以及 ID 令牌
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id)) // 这里很重要,需要 Web 客户端 ID
            .requestEmail()
            .build()

        googleSignInClient = GoogleSignIn.getClient(this, gso)
        firebaseAuth = FirebaseAuth.getInstance()

        // ... 其他初始化代码
    }
}

关于 default_web_client_id
这个 ID 可以在 google-services.json 文件中找到,它通常位于 client 数组中,client_type 为 3 的对象的 oauth_client 数组下的 client_id。或者,你也可以在 Firebase 控制台的 项目设置 -> 通用 页面中找到它(通常以 .apps.googleusercontent.com 结尾)。在 strings.xml 中定义它:

<resources>
    <string name="default_web_client_id" translatable="false">YOUR_WEB_CLIENT_ID_FROM_FIREBASE</string>
</resources>

关于requestIdToken
如果去掉 requestIdToken ,可以实现通过 Google 登录
需要在 https://console.cloud.google.com 添加账户配置,不需要 Firebase 平台,

2.2 启动 Google 登录流程

通常,你会通过一个按钮(例如“使用 Google 登录”按钮)来触发登录流程。

// Kotlin
// 在你的 onCreate 或其他适当位置为按钮设置点击监听器
signInButton.setOnClickListener {
    signInWithGoogle()
}

private fun signInWithGoogle() {
    val signInIntent = googleSignInClient.signInIntent
    startActivityForResult(signInIntent, RC_SIGN_IN) // RC_SIGN_IN 是你定义的请求码
}

companion object {
    private const val RC_SIGN_IN = 9001 // 请求码,任意整数即可
}

2.3 处理登录结果

onActivityResult 方法中,你需要处理 Google 登录的结果,并将其传递给 Firebase Authentication。

// Kotlin
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.common.api.ApiException
import com.google.firebase.auth.GoogleAuthProvider

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

    // 检查请求码是否是 Google Sign-In 的请求码
    if (requestCode == RC_SIGN_IN) {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {
            // Google Sign In 成功,现在使用 Google 账户向 Firebase 验证
            val account = task.getResult(ApiException::class.java)
            Log.d(TAG, "Google sign-in successful: account.idToken=${account.idToken}")
            firebaseAuthWithGoogle(account.idToken!!)
        } catch (e: ApiException) {
            // Google Sign In 失败,更新 UI 或显示错误信息
            Log.w(TAG, "Google sign-in failed", e)
            Toast.makeText(this, "Google 登录失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}

private fun firebaseAuthWithGoogle(idToken: String) {
    Log.d(TAG, "firebaseAuthWithGoogle:$idToken")

    val credential = GoogleAuthProvider.getCredential(idToken, null)
    firebaseAuth.signInWithCredential(credential)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // 登录成功
                Log.d(TAG, "Firebase Google 登录成功")
                val user = firebaseAuth.currentUser
                updateUI(user) // 更新 UI,例如跳转到主页
            } else {
                // 登录失败
                Log.w(TAG, "Firebase Google 登录失败", task.exception)
                Toast.makeText(this, "Firebase Google 登录失败:${task.exception?.message}", Toast.LENGTH_SHORT).show()
                updateUI(null)
            }
        }
}

private fun updateUI(user: FirebaseUser?) {
    if (user != null) {
        // 用户已登录,可以跳转到主页
        Toast.makeText(this, "欢迎, ${user.displayName ?: user.email}", Toast.LENGTH_SHORT).show()
        // 例如:startActivity(Intent(this, HomeActivity::class.java))
        // finish()
    } else {
        // 用户未登录,保持在登录界面
        Toast.makeText(this, "请登录", Toast.LENGTH_SHORT).show()
    }
}

2.4 处理用户状态变化(可选但推荐)

你可以在 Activity 的 onStart() 方法中检查用户是否已登录。

// Kotlin
import com.google.firebase.auth.FirebaseUser

override fun onStart() {
    super.onStart()
    // 检查用户是否已登录 (非空) 并更新 UI
    val currentUser = firebaseAuth.currentUser
    updateUI(currentUser)
}

2.5 退出登录

// Kotlin
private fun signOut() {
    firebaseAuth.signOut() // Firebase 退出登录
    googleSignInClient.signOut().addOnCompleteListener(this) {
        // Google 退出登录成功
        updateUI(null)
        Toast.makeText(this, "已退出登录", Toast.LENGTH_SHORT).show()
    }
}

3. 注意事项和最佳实践

  • 错误处理: 在实际应用中,你需要对 ApiExceptionaddOnCompleteListener 中的 task.exception 进行更详细的错误处理,向用户提供有用的反馈。
  • UI 更新: updateUI() 方法是一个占位符,你需要根据你的应用逻辑来实现它。例如,当用户登录成功时,你可以导航到主屏幕;当用户注销时,可以返回登录屏幕。
  • 安全性:
    • SHA-1 指纹: 确保你提供给 Firebase 的 SHA-1 指纹是正确的。如果你使用了发布版签名,你还需要为发布版签名配置一个 SHA-1 指纹。
    • default_web_client_id 确保你使用了正确的 Web 客户端 ID。
    • 混淆: 如果你的应用使用了 ProGuard 或 R8 进行代码混淆,请确保添加了必要的规则以保留 Firebase Authentication 和 Google Sign-In SDK 的类。通常,这些规则在库中已经定义好了,但在某些情况下你可能需要手动添加。
  • 用户体验:
    • 提供清晰的登录/注册按钮。
    • 在登录过程中显示加载指示器,避免用户误以为应用无响应。
    • 当登录失败时,向用户提供明确的错误信息。
  • Credential Manager (Android 14+): 对于 Android 14 及更高版本,Google 推荐使用 Credential Manager 来简化和统一身份验证流程,它也可以与 Firebase Authentication 结合使用。Credential Manager 提供更现代的 API 来处理各种凭据类型,包括 Google Sign-In。如果你支持 Android 14+,建议研究 Credential Manager。

通过遵循以上步骤,你就可以在你的 Android 应用中成功实现基于 Firebase Authentication 的 Google 登录功能。这个方案既安全又方便,能够为你的用户提供流畅的认证体验。

https://g.co/gemini/share/ae53a923579e


网站公告

今日签到

点亮在社区的每一天
去签到