如何为共享同一Firebase数据库的两款Android应用分离Authentication与Firestore
同一Firebase数据库下实现普通用户与司机的Auth及Firestore隔离方案
嘿,这个场景我之前帮客户落地过,给你整理几个实用的方案,分身份认证区分和Firestore数据隔离两部分来拆解:
一、先搞定Authentication的用户类型区分
核心是给不同用户打上「身份标签」,方便后续权限控制,有两种常用方式:
1. 自定义用户Claims(推荐)
这是Firebase官方推荐的轻量身份区分方式,通过Admin SDK给用户添加userType的自定义声明,比如"regular"(普通用户)或"driver"(司机)。
后端设置示例(Node.js Cloud Functions):
const admin = require('firebase-admin'); exports.setUserType = functions.https.onCall(async (data, context) => { // 确保只有管理员或可信流程能调用(比如注册后的回调) if (!context.auth || !context.auth.token.admin) { throw new functions.https.HttpsError('permission-denied', '无权操作'); } const { uid, userType } = data; await admin.auth().setCustomUserClaims(uid, { userType }); return { success: true }; });
Android客户端获取并验证:
FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnSuccessListener { idToken -> val userType = idToken.claims["userType"] as? String when(userType) { "regular" -> // 跳转到普通用户首页 "driver" -> // 跳转到司机专属界面 else -> // 未设置类型,引导完善身份 } }
2. Firestore用户Profile文档
如果需要存储更多用户关联信息(比如司机的车牌、车辆型号),可以在用户注册后,在Firestore的users集合中创建对应文档,包含userType字段:
// 用户注册成功后写入Profile val user = FirebaseAuth.getInstance().currentUser user?.let { val userProfile = hashMapOf( "userType" to "driver", "licensePlate" to "京A12345", "uid" to it.uid ) FirebaseFirestore.getInstance().collection("users").document(it.uid).set(userProfile) }
二、Firestore数据隔离:用安全规则锁死权限
不管用哪种身份区分方式,最终都要通过Firestore安全规则来确保不同类型的用户只能访问自己的数据,这里提供两种结构方案:
1. 按用户类型拆分集合(清晰直观)
直接创建regularUsers和drivers两个独立集合,规则里只允许对应类型的用户访问:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 普通用户只能访问自己的集合 match /regularUsers/{userId} { allow read, write: if request.auth != null && request.auth.token.userType == 'regular' && request.auth.uid == userId; } // 司机只能访问自己的集合 match /drivers/{userId} { allow read, write: if request.auth != null && request.auth.token.userType == 'driver' && request.auth.uid == userId; } // 如果有公共数据(比如订单),可以单独加规则 match /orders/{orderId} { allow read: if request.auth != null; allow write: if request.auth.token.userType == 'driver'; // 只有司机能创建订单 } } }
2. 同一集合用字段区分(适合数据关联紧密的场景)
如果普通用户和司机的数据结构大部分重合,可以放在同一个users集合,用userType字段区分,规则控制访问:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { // 用户只能读写自己的文档 allow read, write: if request.auth != null && request.auth.uid == userId; // 如果需要同类型用户之间访问(比如司机查看其他司机信息),可以加: // allow read: if request.auth.token.userType == resource.data.userType; } } }
三、额外的安全小Tips
- 禁止客户端直接设置用户类型:一定要通过Admin SDK或Cloud Functions来设置
userType,防止用户在客户端篡改身份。 - 用App Check加固:给两款App都配置Firebase App Check,确保只有你的官方App能访问数据库,拦截恶意请求。
- 测试规则:用Firebase控制台的「规则模拟器」,分别模拟普通用户、司机的访问请求,验证规则是否生效。
内容的提问来源于stack exchange,提问作者Mridul Shukla
相关产品推荐
相关产品推荐

