Firebase quickstart-android 进阶用法、完整业务场景代码、Android 高版本适配、高频报错解决方案**,同时完善辅助模块细节,以及模块间联动逻辑,帮助开发者快速将示例代码落地到实际项目,避开所有集成雷区。
# 一、身份认证类模块(补充进阶用法)
## 1. auth 模块(补充进阶功能+报错解决)
### (1)进阶功能:账号关联与令牌管理
实际开发中,常遇到“匿名登录转永久账号”“多账号关联”(如Google登录关联邮箱账号)、“ID Token 验证”(前后端交互),示例代码如下:
```kotlin
// 1. 匿名登录转永久账号(绑定邮箱/密码)
val auth = FirebaseAuth.getInstance()
val anonymousUser = auth.currentUser ?: return
// 创建邮箱/密码凭证
val credential = EmailAuthProvider.getCredential("test@example.com", "123456")
// 关联账号(匿名账号数据会自动迁移到新账号)
anonymousUser.linkWithCredential(credential)
.addOnSuccessListener { result ->
val user = result.user // 关联后的永久账号
}
.addOnFailureListener { e ->
// 关联失败(如邮箱已被其他账号占用)
}
// 2. ID Token 验证(前端获取Token,后端校验身份)
auth.currentUser?.getIdToken(true) // true表示强制刷新Token
?.addOnSuccessListener { tokenResult ->
val idToken = tokenResult.token // 获取ID Token
// 发送Token到后端,后端通过Firebase Admin SDK校验
Log.d("AuthToken", "ID Token: $idToken")
}
// 3. 多账号切换(退出当前账号,登录另一个账号,保留之前账号会话)
auth.signInWithEmailAndPassword(email1, password1) // 登录账号1
auth.signInWithEmailAndPassword(email2, password2) // 登录账号2(默认覆盖当前会话)
// 如需保留多账号会话,需使用 FirebaseAuth.getInstance(FirebaseApp.getInstance("secondary")) 创建新实例
```
### (2)高频报错及解决方案
- **报错1**:Google登录提示“signInResult:failed code=10”(无权限)
解决:① 在 Firebase 控制台「项目设置→应用→Android应用→SHA证书指纹」,添加本地调试SHA-1和发布版SHA-1;② 确保 Google 登录在 Firebase 控制台「Authentication→登录方式」中已开启;③ 同步 Gradle 后,清理项目(Build→Clean Project)再运行。
- **报错2**:手机号验证码提示“Too many requests”(请求过于频繁)
解决:在 Firebase 控制台「Authentication→登录方式→手机号」,添加测试手机号(无需真实验证码,直接通过测试模式验证);生产环境需限制验证码发送频率(如1分钟内最多1次)。
- **报错3**:注销账号后,重新登录提示“user not found”
解决:注销账号时,需先调用 `auth.signOut()` 退出登录,再调用 `auth.currentUser?.delete()` 删除账号,避免会话残留导致的异常。
## 2. auth-phone 模块(补充细节优化)
该模块核心补充「SMS Retriever API 自动填充验证码」,无需用户手动输入,优化用户体验,完整配置步骤如下:
```kotlin
// 1. 添加依赖(模块已内置,可参考)
implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
// 2. 注册 SMS Retriever 广播接收器
class SmsBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent?.action) {
val extras = intent.extras
val status = extras?.get(SmsRetriever.EXTRA_STATUS) as Status
when (status.statusCode) {
SmsRetriever.STATUS_SUCCESS -> {
// 获取验证码短信内容
val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
// 提取验证码(示例:短信内容为“【Firebase】您的验证码是123456”)
val smsCode = message.replace(Regex("[^0-9]"), "")
// 自动填充到输入框
findViewById<EditText>(R.id.smsCodeEt).setText(smsCode)
}
SmsRetriever.STATUS_TIMEOUT -> {
// 验证码获取超时(5分钟),提示用户手动输入
}
}
}
}
}
// 3. 在 Activity 中启动 SMS Retriever
private fun startSmsRetriever() {
val client = SmsRetriever.getClient(this)
val task = client.startSmsRetriever()
task.addOnSuccessListener {
// 启动成功,等待接收验证码
}
task.addOnFailureListener {
// 启动失败,提示用户手动输入
}
}
```
注意:短信内容需包含 App 的签名哈希值(可通过 Firebase 控制台获取),否则无法自动提取验证码。
# 二、数据库类模块(补充高级用法+安全规则)
## 1. database 模块(补充安全规则+离线优化)
### (1)安全规则进阶配置(生产环境必配)
此前仅提供测试规则(全读写),生产环境需按“用户只能操作自己的数据”配置规则,示例如下(适配 /users/{uid} 路径):
```json
// 生产环境安全规则(仅授权用户可读写自己的信息)
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid", // 仅当前登录用户可读取自己的数据
".write": "$uid === auth.uid" // 仅当前登录用户可修改自己的数据
}
},
"public": {
".read": true, // 公开可读(如公告、商品列表)
".write": false // 禁止客户端写入,仅通过云函数修改
}
}
}
```
规则调试技巧:在 Firebase 控制台「Realtime Database→规则→模拟器」,可模拟不同用户(登录/未登录)的读写操作,验证规则是否生效。
### (2)离线优化进阶
Realtime Database 默认开启离线持久化,但可通过以下配置优化离线体验:
```kotlin
val database = FirebaseDatabase.getInstance()
// 1. 限制离线缓存大小(避免占用过多内存,默认无限制)
database.setPersistenceCacheSizeBytes(1024 * 1024 * 10) // 10MB
// 2. 手动控制离线同步(断网时暂停同步,联网后恢复)
database.goOffline() // 暂停同步(断网时调用)
database.goOnline() // 恢复同步(联网时调用)
// 3. 监听网络状态,自动切换离线/在线模式
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
database.goOnline() // 联网,恢复同步
}
override fun onLost(network: Network) {
super.onLost(network)
database.goOffline() // 断网,暂停同步
}
})
```
## 2. firestore 模块(补充分页+批量操作+索引优化)
### (1)分页查询进阶(避免一次性加载过多数据)
实际开发中,列表数据需分页加载(如下拉加载更多),示例代码如下:
```kotlin
val db = FirebaseFirestore.getInstance()
val usersCol = db.collection("users")
var lastVisible: DocumentSnapshot? = null // 记录上一页最后一条数据的快照
// 加载第一页(10条数据)
fun loadFirstPage() {
usersCol.orderBy("createTime", Query.Direction.DESCENDING)
.limit(10)
.get()
.addOnSuccessListener { snapshot ->
if (!snapshot.isEmpty) {
lastVisible = snapshot.documents.last() // 记录最后一条数据
// 解析数据并展示
for (doc in snapshot) {
val user = doc.toObject(User::class.java)
}
}
}
}
// 加载下一页(下拉加载更多)
fun loadNextPage() {
if (lastVisible == null) return
usersCol.orderBy("createTime", Query.Direction.DESCENDING)
.startAfter(lastVisible) // 从上次最后一条数据之后开始加载
.limit(10)
.get()
.addOnSuccessListener { snapshot ->
if (!snapshot.isEmpty) {
lastVisible = snapshot.documents.last()
// 解析数据并追加到列表
} else {
// 没有更多数据
}
}
}
```
### (2)批量操作(避免频繁调用API)
批量新增/删除/修改数据,可减少API调用次数,提升性能:
```kotlin
val db = FirebaseFirestore.getInstance()
val batch = db.batch()
// 1. 批量新增3条数据
val user1 = User("1", "张三", 20)
val user2 = User("2", "李四", 22)
val user3 = User("3", "王五", 25)
batch.set(usersCol.document(user1.id), user1)
batch.set(usersCol.document(user2.id), user2)
batch.set(usersCol.document(user3.id), user3)
// 2. 批量删除2条数据
batch.delete(usersCol.document("4"))
batch.delete(usersCol.document("5"))
// 3. 批量修改1条数据
batch.update(usersCol.document("1"), "age", 21)
// 执行批量操作
batch.commit()
.addOnSuccessListener { Log.d("Firestore", "批量操作成功") }
.addOnFailureListener { e -> Log.e("Firestore", "批量操作失败:${e.message}") }
```
### (3)索引优化(解决复合查询卡顿)
当复合查询(如 whereGreaterThan + whereEqualTo)数据量较大时,需创建复合索引提升查询速度,步骤如下:
1. 运行查询,Logcat 会提示“Missing index”,并给出索引创建链接;
2. 点击链接,自动跳转到 Firebase 控制台「Firestore→索引→复合索引」,确认索引字段(如 age、city)和排序方式;
3. 创建索引(需等待几分钟生效),生效后查询速度会显著提升。
注意:索引会占用额外存储空间,避免创建不必要的索引(如单一字段查询无需创建复合索引)。
## 3. firestore-kotlin 模块(补充协程完整用法)
该模块基于 Kotlin 协程,替代传统回调,代码更简洁,支持 Flow 实时监听,完整示例如下:
```kotlin
// 1. 依赖(模块已内置)
implementation 'com.google.firebase:firebase-firestore-ktx:24.10.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
// 2. 协程版查询(单条数据)
lifecycleScope.launch {
val userDoc = usersCol.document("1").get().await() // 替代回调,直接获取结果
if (userDoc.exists()) {
val user = userDoc.toObject(User::class.java)
} else {
// 数据不存在
}
}
// 3. Flow 实时监听(数据变化自动更新)
lifecycleScope.launch {
usersCol.document("1").snapshots().collect { snapshot ->
val user = snapshot.toObject(User::class.java)
// 数据变化,更新UI
}
}
// 4. 协程版批量操作
lifecycleScope.launch {
try {
db.runTransaction { tx ->
val docRef = usersCol.document("1")
val balance = tx.get(docRef).getLong("balance") ?: 0
if (balance < 100) throw Exception("余额不足")
tx.update(docRef, "balance", balance - 100)
null
}.await() // 协程等待事务完成
Log.d("Firestore", "事务成功")
} catch (e: Exception) {
Log.e("Firestore", "事务失败:${e.message}")
}
}
```
# 三、分析与监控类模块(补充高级配置+数据解读)
## 1. analytics 模块(补充转化跟踪+自定义维度)
### (1)转化跟踪(如“注册→付费”转化)
通过设置转化事件,可在 Firebase 控制台查看用户转化路径,示例代码如下:
```kotlin
val analytics = FirebaseAnalytics.getInstance(this)
// 1. 上报“注册”事件(转化起点)
analytics.logEvent(FirebaseAnalytics.Event.SIGN_UP, Bundle().apply {
putString(FirebaseAnalytics.Param.METHOD, "email") // 注册方式
})
// 2. 上报“付费”事件(转化终点)
analytics.logEvent(FirebaseAnalytics.Event.PURCHASE, Bundle().apply {
putString(FirebaseAnalytics.Param.PRODUCT_ID, "vip_1_month") // 商品ID
putDouble(FirebaseAnalytics.Param.VALUE, 19.99) // 商品金额
putString(FirebaseAnalytics.Param.CURRENCY, "CNY") // 货币类型
})
```
查看转化数据: Firebase 控制台「Analytics→转化」,创建转化事件(如“付费”),即可查看“注册→付费”的转化漏斗、转化时长等数据。
### (2)自定义维度(按用户/设备分组分析)
通过自定义维度,可按“用户等级”“设备型号”“地区”等维度分析数据,示例:
```kotlin
// 1. 在 Firebase 控制台「Analytics→自定义定义→自定义维度」,创建维度(如“user_level”)
// 2. 代码中设置维度
analytics.setUserProperty("user_level", "vip") // 用户等级:vip
analytics.setUserProperty("device_model", Build.MODEL) // 设备型号:Pixel 8
analytics.setUserProperty("region", "Beijing") // 地区:北京
// 3. 上报事件时,可关联维度
analytics.logEvent("page_view", Bundle().apply {
putString("page_name", "home")
putString("user_level", "vip") // 关联用户等级维度
})
```
## 2. crashlytics 模块(补充崩溃分析+自定义归因)
### (1)崩溃分析进阶(定位崩溃原因)
Crashlytics 不仅能捕获崩溃,还能通过自定义日志、用户信息,快速定位崩溃场景:
```kotlin
val crashlytics = FirebaseCrashlytics.getInstance()
// 1. 设置用户ID(关联崩溃用户)
crashlytics.setUserId("123456")
// 2. 设置自定义键值对(记录崩溃时的场景信息)
crashlytics.setCustomKey("page", "home") // 崩溃时所在页面
crashlytics.setCustomKey("network", "wifi") // 崩溃时网络状态
crashlytics.setCustomKey("version", BuildConfig.VERSION_NAME) // App版本
// 3. 记录自定义日志(辅助定位崩溃原因)
crashlytics.log("用户点击了支付按钮,开始请求接口")
crashlytics.log("接口返回数据:$response")
// 4. 捕获崩溃(主动触发/异常捕获)
try {
val list = emptyList<String>()
val str = list[0] // 主动触发数组越界崩溃
} catch (e: IndexOutOfBoundsException) {
// 记录崩溃,并添加自定义描述
crashlytics.recordException(Throwable("支付页面数组越界:${e.message}", e))
}
```
查看崩溃详情: Firebase 控制台「Crashlytics→崩溃」,可查看崩溃堆栈、用户ID、自定义键值对、日志,快速定位问题(如“支付页面,wifi网络,App 1.0.0版本,数组越界”)。
### (2)高频报错及解决
- **报错1**:崩溃不被捕获,Logcat 提示“Crashlytics could not find the manifest”
解决:检查模块的 AndroidManifest.xml 中,是否添加了 Crashlytics 的 meta-data 配置(模块已内置,若缺失可手动添加):
`<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="true" />`
- **报错2**:崩溃数据延迟超过10分钟
解决:调试时,在 Application 类中添加初始化代码,强制开启调试模式:
`FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true)
if (BuildConfig.DEBUG) {
FirebaseCrashlytics.getInstance().setCustomKey("debug_mode", true)
}`
## 3. performance 模块(补充自定义性能跟踪+优化建议)
该模块除了默认监控启动时间、网络请求,还可自定义跟踪“页面加载时间”“接口请求耗时”,示例:
```kotlin
val performance = FirebasePerformance.getInstance()
// 1. 自定义跟踪“页面加载时间”(从页面创建到渲染完成)
val pageTrace = performance.newTrace("home_page_load")
pageTrace.start() // 页面创建时启动跟踪
// 页面渲染完成后,停止跟踪
pageTrace.stop()
// 2. 跟踪“接口请求耗时”
val httpMetric = performance.newHttpMetric("https://api.example.com/pay", HttpMethod.POST)
httpMetric.start() // 发起请求时启动
// 请求完成后,停止跟踪并设置请求信息
httpMetric.setRequestPayloadSize(1024) // 请求体大小(字节)
httpMetric.setResponsePayloadSize(2048) // 响应体大小(字节)
httpMetric.setHttpResponseCode(200) // 响应码
httpMetric.stop()
// 3. 查看性能数据:Firebase 控制台「Performance→自定义跟踪」
```
优化建议:若监控到“启动时间过长”,可通过 Performance 控制台查看启动流程中的耗时环节(如初始化第三方SDK),针对性优化(如延迟初始化非核心SDK)。
## 4. remoteconfig 模块(补充A/B测试+配置缓存优化)
### (1)A/B测试(按用户分组下发不同配置)
通过 Remote Config 结合 Firebase A/B Testing,可给不同用户组下发不同配置(如50%用户看到“立即购买”,50%用户看到“限时优惠”),步骤如下:
1. 在 Firebase 控制台「Remote Config」,创建配置项(如“button_text”);
2. 在「A/B Testing」,创建实验,选择“Remote Config”作为实验变量,设置用户分组(如按设备型号、地区分组);
3. 代码中正常拉取配置,Remote Config 会自动根据用户分组下发对应值:
`val remoteConfig = FirebaseRemoteConfig.getInstance()
// 拉取配置(调试时缓存过期时间设为0,实时生效)
remoteConfig.fetchAndActivate()
.addOnSuccessListener {
val btnText = remoteConfig.getString("button_text")
findViewById<Button>(R.id.btn).text = btnText
}`
### (2)配置缓存优化(减少网络请求)
Remote Config 默认有缓存(默认12小时),可根据场景调整缓存时间,避免频繁拉取配置:
```kotlin
// 1. 调试模式:缓存过期时间0,实时拉取最新配置
remoteConfig.fetch(0)
.addOnSuccessListener {
remoteConfig.activate() // 激活配置
}
// 2. 生产环境:缓存1小时,减少网络请求
remoteConfig.fetch(3600) // 缓存时间(秒)
.addOnSuccessListener {
remoteConfig.activate()
}
// 3. 强制刷新配置(如用户手动触发刷新)
remoteConfig.fetchAndActivate() // 忽略缓存,强制拉取
```
# 四、云存储模块(storage 补充进阶功能+权限优化)
## 1. 进阶功能:文件压缩+断点续传
### (1)图片上传前压缩(减少上传时间和存储空间)
```kotlin
// 1. 图片压缩工具类(压缩到指定尺寸和质量)
fun compressImage(file: File): File {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(file.path, options)
// 计算压缩比例(示例:压缩到1080p以下)
val targetWidth = 1080
val targetHeight = 1920
val widthRatio = Math.round(options.outWidth.toFloat() / targetWidth.toFloat())
val heightRatio = Math.round(options.outHeight.toFloat() / targetHeight.toFloat())
val inSampleSize = if (widthRatio > 0 || heightRatio > 0) {
Math.min(widthRatio, heightRatio)
} else {
1
}
options.inJustDecodeBounds = false
options.inSampleSize = inSampleSize
val bitmap = BitmapFactory.decodeFile(file.path, options)
// 保存压缩后的图片
val compressedFile = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "compressed_${System.currentTimeMillis()}.jpg")
val outputStream = FileOutputStream(compressedFile)
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream) // 质量80%
outputStream.close()
return compressedFile
}
// 2. 上传压缩后的图片
val originalFile = File("/sdcard/avatar.jpg")
val compressedFile = compressImage(originalFile)
val avatarRef = storage.reference.child("images").child(userId).child("avatar.jpg")
avatarRef.putFile(Uri.fromFile(compressedFile))
.addOnSuccessListener { /* 上传成功处理 */ }
```
### (2)断点续传(避免网络中断后重新上传)
Storage 支持断点续传,通过 UploadTask 的 pause()、resume() 方法实现:
```kotlin
val uploadTask = avatarRef.putFile(Uri.fromFile(compressedFile))
var uploadTaskSnapshot: UploadTask.TaskSnapshot? = null
// 暂停上传(如网络中断时)
findViewById<Button>(R.id.pauseBtn).setOnClickListener {
if (uploadTask.isInProgress) {
uploadTask.pause()
uploadTaskSnapshot = uploadTask.snapshot // 记录当前上传进度
}
}
// 恢复上传(如网络恢复时)
findViewById<Button>(R.id.resumeBtn).setOnClickListener {
if (uploadTask.isPaused) {
uploadTask.resume()
}
}
// 监听上传进度
uploadTask.addOnProgressListener { snapshot ->
val progress = (100.0 * snapshot.bytesTransferred) / snapshot.totalByteCount
Log.d("Storage", "上传进度:$progress%")
}
```
## 2. 权限优化(生产环境必配)
Storage 测试规则(全读写)存在安全隐患,生产环境需按“用户只能操作自己的文件”配置规则,示例:
```json
// 生产环境 Storage 规则
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// 用户只能上传/下载自己的头像(路径:/images/{uid}/*)
match /images/{uid}/{allPaths=**} {
allow read: if request.auth != null && request.auth.uid == uid;
allow write: if request.auth != null && request.auth.uid == uid
&& request.resource.contentType.matches('image/.*') // 仅允许上传图片
&& request.resource.size < 5 * 1024 * 1024; // 限制图片大小不超过5MB
}
// 公开可读的文件(如App图标)
match /public/{allPaths=**} {
allow read: if true;
allow write: if false;
}
}
}
```
# 五、消息推送类模块(补充适配+交互优化)
## 1. messaging 模块(补充 Android 13+ 适配+自定义通知)
### (1)Android 13+ 推送权限适配(必做)
Android 13(API 33)及以上,推送通知需申请 POST_NOTIFICATIONS 权限,示例代码:
```kotlin
// 1. 在 AndroidManifest.xml 中添加权限
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
// 2. 代码中申请权限(Android 13+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
1001 // 权限请求码
)
}
}
// 3. 权限请求回调
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 1001) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限授予,可正常接收推送
} else {
// 权限拒绝,无法接收前台通知(后台推送仍可接收,但无通知栏展示)
}
}
}
```
### (2)自定义通知样式(如大图通知、进度条通知)
```kotlin
// 在 MyFCMService 的 onMessageReceived 中,自定义通知样式
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
val title = remoteMessage.notification?.title ?: "通知标题"
val body = remoteMessage.notification?.body ?: "通知内容"
// 1. 自定义通知渠道(Android 8.0+ 必配)
val channelId = "fcm_channel"
val channelName = "FCM 推送通知"
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
// 2. 自定义通知布局(大图通知)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_large_icon))
.setStyle(NotificationCompat.BigPictureStyle()
.bigPicture(BitmapFactory.decodeResource(resources, R.drawable.big_image))
.bigLargeIcon(null)) // 隐藏大图通知的小图标
.setAutoCancel(true) // 点击通知后自动取消
.setContentIntent(getPendingIntent()) // 点击通知跳转的页面
// 3. 显示通知
notificationManager.notify(System.currentTimeMillis().toInt(), notificationBuilder.build())
}
// 点击通知跳转的页面
private fun getPendingIntent(): PendingIntent {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("from_notification", true) // 标记是否从通知跳转
return PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
```
### (3)高频报错及解决
- **报错1**:Android 13+ 接收不到通知
解决:① 申请 POST_NOTIFICATIONS 权限;② 确认通知渠道已创建;③ 检查手机设置中,App 的通知权限是否开启。
- **报错2**:后台推送接收不到(App 进程被杀死)
解决:① 集成 Firebase Messaging Service 后,确保 Service 在 AndroidManifest 中正确注册;② 针对国产手机(华为、小米、OPPO),引导用户将 App 加入后台白名单(设置→应用→后台运行权限→允许)。
## 2. inappmessaging 模块(补充触发条件+样式自定义)
该模块用于展示应用内消息(如弹窗、横幅),核心是“在 Firebase 控制台配置触发条件”,补充代码中自定义样式和触发逻辑:
```kotlin
val inAppMessaging = FirebaseInAppMessaging.getInstance()
// 1. 开启/关闭应用内消息(如用户拒绝接收时关闭)
inAppMessaging.setMessagesSuppressed(false) // 开启
inAppMessaging.setMessagesSuppressed(true) // 关闭
// 2. 自定义消息展示样式(如修改弹窗背景色、文字颜色)
inAppMessaging.addClickListener { inAppMessage, action ->
// 点击消息按钮的回调
Log.d("InAppMessaging", "点击了按钮:${action.actionText}")
}
// 3. 手动触发消息展示(默认由 Firebase 控制台配置的条件触发,可手动触发测试)
inAppMessaging.triggerEvent("custom_event") // 触发名为“custom_event”的事件,展示对应消息
```
配置触发条件: Firebase 控制台「In-App Messaging→创建消息」,选择消息样式(弹窗/横幅/卡片),设置触发条件(如“用户登录后”“用户点击某按钮后”),保存后即可在 App 中触发展示。
# 六、安全与工具类模块(补充完整集成+部署步骤)
## 1. appcheck 模块(补充两种验证方式+调试模式)
App Check 用于防止恶意请求,支持两种验证方式:Recaptcha V3(适用于所有 Android 设备)、Play Integrity(仅适用于 Google Play 分发的设备),完整集成代码如下:
### (1)Recaptcha V3 集成
```kotlin
// 1. 添加依赖(模块已内置)
implementation 'com.google.firebase:firebase-appcheck-recaptcha:17.1.2'
// 2. 在 Application 类中初始化
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// 初始化 App Check
val appCheck = FirebaseAppCheck.getInstance()
appCheck.installAppCheckProviderFactory(
RecaptchaAppCheckProviderFactory.getInstance()
)
// 调试模式(开发时开启,避免拦截合法请求)
if (BuildConfig.DEBUG) {
appCheck.setTokenAutoRefreshEnabled(true)
appCheck.getAppCheckToken(true)
.addOnSuccessListener { tokenResult ->
Log.d("AppCheck", "调试 Token:${tokenResult.token}")
}
}
}
}
```
### (2)Play Integrity 集成(推荐 Google Play 分发的 App)
```kotlin
// 1. 添加依赖
implementation 'com.google.firebase:firebase-appcheck-playintegrity:17.1.2'
// 2. 初始化(替换 Recaptcha 初始化代码)
appCheck.installAppCheckProviderFactory(
PlayIntegrityAppCheckProviderFactory.getInstance()
)
```
注意:Play Integrity 需在 Google Play 控制台添加 App,且 App 需签名后才能正常使用。
## 2. functions 模块(补充云函数部署+客户端调用细节)
该模块核心是“调用云端自定义函数”,需先在 Firebase 控制台部署云函数,再在客户端调用,完整步骤如下:
### (1)部署云函数(Node.js 示例)
1. 安装 Firebase CLI:`npm install -g firebase-tools`;
2. 登录 Firebase:`firebase login`;
3. 初始化云函数:`firebase init functions`,选择对应 Firebase 项目;
4. 修改 `functions/index.js`,编写云函数(示例:计算两个数的和):
`const functions = require("firebase-functions");
exports.addNumbers = functions.https.onCall((data, context) => {
// 验证用户是否登录(可选)
if (!context.auth) {
throw new functions.https.HttpsError("unauthenticated", "用户未登录");
}
const num1 = data.num1;
const num2 = data.num2;
return { result: num1 + num2 };
});`
5. 部署云函数:`firebase deploy --only functions`,部署成功后,会生成云函数调用地址。
### (2)客户端调用云函数(Android 代码)
```kotlin
val functions = FirebaseFunctions.getInstance()
// 调用云函数 addNumbers
val data = hashMapOf(
"num1" to 10,
"num2" to 20
)
functions.getHttpsCallable("addNumbers")
.call(data)
.addOnSuccessListener { result ->
val resultData = result.data as Map<*, *>
val sum = resultData["result"] as Long
Log.d("Functions", "计算结果:$sum") // 输出 30
}
.addOnFailureListener { e ->
// 处理调用失败(如用户未登录、云函数报错)
if (e is FirebaseFunctionsException) {
val code = e.code
val message = e.message
Log.e("Functions", "调用失败:$code - $message")
}
}
```
## 3. mlkit 模块(补充各 AI 功能完整代码)
该模块演示 ML Kit 移动端 AI 能力,补充 OCR 文字识别、人脸检测、条码扫描的完整代码,适配 Android 高版本:
### (1)OCR 文字识别(识别图片中的文字)
```kotlin
// 1. 添加依赖(模块已内置)
implementation 'com.google.mlkit:text-recognition-chinese:16.0.0'
// 2. 识别图片中的文字(从相册选择图片)
private fun recognizeText(bitmap: Bitmap) {
val textRecognizer = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())
val inputImage = InputImage.fromBitmap(bitmap, 0) // 0 是图片旋转角度
textRecognizer.process(inputImage)
.addOnSuccessListener { visionText ->
// 识别成功,提取文字
val text = visionText.text
Log.d("MLKit", "识别结果:$text")
// 提取每行文字
for (block in visionText.textBlocks) {
for (line in block.lines) {
Log.d("MLKit", "行文字:${line.text}")
}
}
}
.addOnFailureListener { e ->
Log.e("MLKit", "识别失败:${e.message}")
}
}
```
### (2)人脸检测(检测图片中的人脸,获取人脸信息)
```kotlin
// 1. 添加依赖
implementation 'com.google.mlkit:face-detection:16.1.5'
// 2. 人脸检测
private fun detectFaces(bitmap: Bitmap) {
val faceDetector = FaceDetection.getClient(
FaceDetectorOptions.Builder()
.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST) // 快速检测
.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL) // 检测人脸关键点(眼睛、鼻子等)
.setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL) // 检测表情、是否戴眼镜
.build()
)
val inputImage = InputImage.fromBitmap(bitmap, 0)
faceDetector.process(inputImage)
.addOnSuccessListener { faces ->
// 检测到的人脸列表
for (face in faces) {
// 人脸边界
val boundingBox = face.boundingBox
// 表情(微笑程度:0.0~1.0)
val smileProbability = face.smilingProbability ?: 0.0
// 是否戴眼镜
val isWearingGlasses = face.rightEyeOpenProbability ?: 0.0 > 0.5
Log.d("MLKit", "检测到人脸:微笑程度=$smileProbability,是否戴眼镜=$isWearingGlasses")
}
}
.addOnFailureListener { e ->
Log.e("MLKit", "人脸检测失败:${e.message}")
}
}
```
## 4. dynamiclinks 模块(补充域名配置+跳转逻辑)
动态链接用于跨平台跳转(如从网页/微信分享链接,跳转到 App,未安装则引导下载),完整配置步骤如下:
### (1)在 Firebase 控制台配置动态链接域名
1. 进入 Firebase 控制台「Dynamic Links→开始使用」,创建动态链接域名(如“xxx.page.link”);
2. 验证域名所有权(按提示添加 DNS 解析或上传验证文件);
3. 创建动态链接,设置“深链接”(如“myapp://home”)、“未安装 App 时的跳转链接”(如应用商店下载链接)。
### (2)客户端接收动态链接跳转
```kotlin
// 1. 在 AndroidManifest.xml 中配置深链接
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="home"
android:scheme="myapp" /> // 深链接 scheme:myapp://home
</intent-filter>
</activity>
// 2. 在 MainActivity 中接收动态链接
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 接收动态链接
FirebaseDynamicLinks.getInstance()
.getDynamicLink(intent)
.addOnSuccessListener { pendingDynamicLinkData ->
var deepLink: Uri? = null
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.link
}
// 处理深链接(如跳转到对应页面)
deepLink?.let {
if (it.toString().contains("home")) {
// 跳转到首页
} else if (it.toString().contains("product")) {
// 跳转到商品详情页,提取商品ID
val productId = it.getQueryParameter("product_id")
}
}
}
.addOnFailureListener { e ->
Log.e("DynamicLinks", "获取动态链接失败:${e.message}")
}
}
```
# 七、辅助模块(补充细节+解决常见问题)
## 1. internal 模块(核心作用+缺失解决)
该模块是 **项目内部工具模块**,非业务功能,核心作用:
- 提供基础工具类(如权限申请工具、日志工具、UI 工具),供其他模块复用;
- 统一管理依赖版本(如 Firebase SDK 版本、AndroidX 依赖版本),避免模块间版本冲突;
- 封装通用逻辑(如 Firebase 初始化、用户信息存储),减少重复代码。
补充此前报错(internal 模块缺失)的进阶解决方法:
```bash
# 方法1:手动下载子模块(无需重新克隆项目)
cd /Users/syxny/Workspace/AndroidStudioProjects/quickstart-android2
git submodule init auth/internal
git submodule update auth/internal
# 方法2:手动创建 internal 目录并添加基础文件(应急)
mkdir -p auth/internal/src/main/java/com/google/firebase/quickstart/auth/internal
# 从 Firebase 官方仓库下载 internal 模块的核心文件,放入上述目录
# 官方仓库 internal 模块地址:https://github.com/firebase/quickstart-android/tree/master/auth/internal
```
## 2. appdistribution 模块(应用分发+测试反馈)
该模块用于测试包分发,替代蒲公英、TestFlight,支持测试反馈收集,核心用法:
```kotlin
// 1. 添加依赖(模块已内置)
implementation 'com.google.firebase:firebase-appdistribution:16.0.1'
// 2. 初始化 App Distribution
val appDistribution = FirebaseAppDistribution.getInstance()
// 3. 检查更新(测试包更新)
appDistribution.checkForNewRelease()
.addOnSuccessListener { release ->
if (release != null) {
// 有新的测试包,提示用户更新
appDistribution.updateApp()
}
}
// 4. 收集测试反馈(用户点击反馈按钮时调用)
findViewById<Button
```
Firebase quickstart-android 各模块功能深度补充详解
符哥20082026-03-20 18:13
相关推荐
Sharewinfo_BJ9 小时前
拒绝“盲人摸象”!打破数据孤岛,重塑零售决策力Azure DevOps10 小时前
Azure DevOps:应用远程MCP服务器,提升工作效率SSONICX10 小时前
ESP32:6.ADC迅易科技10 小时前
在 Azure 容器化部署 OpenClaw:从零到生产环境实战指南步步为营DotNet11 小时前
深入剖析.NET 11中Microsoft.Extensions.AI的应用与优化 前言05大叔11 小时前
AI智能伴侣项目roman_日积跬步-终至千里11 小时前
【论文ing】强化学习重塑 NL2SQL:单轮对齐、多轮交互与细粒度评估的最新进展(2020–2026)梦想的旅途21 天前
企业微信 RPA 自动化集成方案