Xcode项目集成Firebase App Check后Firestore权限问题排查
Firebase App Check集成后Firestore权限问题排查
问题背景
我正尝试在Xcode项目中集成Firebase App Check,确保只有我的应用能访问Firebase Database。已在Firebase控制台完成App Check配置,并用DeviceCheck生成密钥,同时修改了Firestore安全规则,设置为仅当请求携带有效App Check令牌时允许访问(应用无需用户认证)。但应用无法获取数据,控制台提示权限不足;若改为开放规则则能正常访问,说明问题出在App Check的代码集成环节。
当前Firestore规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth.token.app_check != null; } } }
Swift集成代码
// // Gossip_GirlApp.swift // Gossip-Girl // // Created by Julius Pleunes on 25/11/2024. // import SwiftUI import Firebase import FirebaseAppCheck @main struct Gossip_GirlApp: App { init() { FirebaseApp.configure() // 配置App Check使用DeviceCheck AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory()) // 调试:开启Firebase日志 FirebaseConfiguration.shared.setLoggerLevel(.debug) print("✅ Firebase 和 App Check 已配置完成") // 调试:获取App Check令牌 AppCheck.appCheck().token(forcingRefresh: true) { token, error in if let error = error { print("⚠️ 获取App Check令牌失败:\(error.localizedDescription)") } else if let token = token?.token { print("✅ App Check令牌:\(token)") } else { print("⚠️ App Check令牌为空") } } // 测试Firestore访问 let db = Firestore.firestore() db.collection("posts").getDocuments { snapshot, error in if let error = error { print("⚠️ 获取帖子失败:\(error.localizedDescription)") } else if let documents = snapshot?.documents { print("✅ 成功获取帖子:") for document in documents { print("\(document.documentID): \(document.data())") } } else { print("⚠️ 'posts'集合中无文档。") } } } var body: some Scene { WindowGroup { MainView() // 以标签栏视图启动 } } }
控制台错误信息
⚠️ 获取帖子失败:Missing or insufficient permissions.
排查和解决方案
1. 修正Firestore规则:适配未认证场景
你的规则中使用request.auth.token.app_check,但应用无需用户认证,未登录用户的request.auth为空,直接导致规则判定失败。未认证场景下,应使用request.app对象验证App Check令牌:
修改后的规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.app != null; } } }
request.app != null表示请求已通过App Check验证,是无需用户登录场景的正确写法。
2. 调整异步调用顺序:确保令牌就绪后再访问Firestore
你在init中同时发起了App Check令牌请求和Firestore请求,但Firestore请求可能在令牌获取完成前就发送了,此时请求未携带有效令牌,触发权限错误。调整代码,让Firestore请求在令牌获取成功后执行:
init() { FirebaseApp.configure() AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory()) FirebaseConfiguration.shared.setLoggerLevel(.debug) print("✅ Firebase 和 App Check 已配置完成") // 先获取App Check令牌,再发起Firestore请求 AppCheck.appCheck().token(forcingRefresh: true) { token, error in if let error = error { print("⚠️ 获取App Check令牌失败:\(error.localizedDescription)") } else if let token = token?.token { print("✅ App Check令牌:\(token)") // 令牌就绪后执行Firestore请求 self.testFirestoreAccess() } else { print("⚠️ App Check令牌为空") } } } private func testFirestoreAccess() { let db = Firestore.firestore() db.collection("posts").getDocuments { snapshot, error in if let error = error { print("⚠️ 获取帖子失败:\(error.localizedDescription)") } else if let documents = snapshot?.documents { print("✅ 成功获取帖子:") for document in documents { print("\(document.documentID): \(document.data())") } } else { print("⚠️ 'posts'集合中无文档。") } } }
3. 验证App Check控制台配置
- 确认Firebase控制台App Check页面已为iOS应用启用DeviceCheck,且正确上传了Apple开发者后台生成的DeviceCheck密钥。
- 检查
GoogleService-Info.plist是否正确添加到项目,其中APP_ID等配置信息无误。 - 调试阶段可临时启用App Check调试令牌验证规则:
同时在Firebase控制台添加调试令牌,验证通过后再切换回DeviceCheck。// 仅调试环境使用 let providerFactory = AppCheckDebugProviderFactory() AppCheck.setAppCheckProviderFactory(providerFactory)
内容的提问来源于stack exchange,提问作者Julius Pleunes
相关产品推荐
相关产品推荐

