Swift环境下Firebase集成Facebook登录的正确方式及权限拒绝排查
Swift环境中Firebase实现Facebook登录的正确方式及权限问题排查
嗨,我来帮你理顺这两个问题,先从正确的登录实现说起:
一、Swift中用Firebase实现Facebook登录的完整步骤
前期配置(必须做!)
- Firebase控制台配置:先在Firebase控制台添加你的iOS应用,填对Bundle ID,下载
GoogleService-Info.plist放到Xcode项目里,记得勾选「Copy items if needed」。然后进入「Authentication」→「登录方法」,启用Facebook登录,填入你的Facebook App ID和App Secret。 - Facebook开发者平台配置:打开你的Facebook测试应用,进入「产品」→「Facebook登录」→「设置」,在「iOS」栏填好你的Bundle ID,把Firebase控制台里的「OAuth重定向URI」复制到Facebook的「有效的OAuth重定向URI」里。另外,还要在Facebook的「基本设置」里填好「显示名称」,确保和Firebase里的一致。
- Xcode项目配置:在
Info.plist里添加:- URL Scheme:格式是
fb<你的Facebook App ID>(比如fb123456789) - 新增
LSApplicationQueriesSchemes数组,添加fbapi、fb-messenger-share-api、fbauth2、fbshareextension这几个值。
- URL Scheme:格式是
代码实现
- 导入必要的框架:
import FirebaseAuth import FBSDKLoginKit
- 在AppDelegate/SceneDelegate里初始化Firebase:
// AppDelegate示例 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() return true }
- 完整的登录按钮点击事件(补全你提供的代码片段):
@IBAction func InicioSesionFacebook(_ sender: Any) { esperaSesion.isHidden = false esperaSesion.startAnimating() let fbLoginManager = LoginManager() // 请求必要权限,public_profile和email是基础权限 fbLoginManager.logIn(permissions: ["public_profile", "email"], from: self) { [weak self] result, error in guard let self = self else { return } self.esperaSesion.stopAnimating() self.esperaSesion.isHidden = true // 处理登录错误 if let error = error { print("Facebook登录失败:\(error.localizedDescription)") return } // 用户取消登录 guard let result = result, !result.isCancelled else { print("用户取消了Facebook登录") return } // 获取Facebook访问令牌 guard let fbToken = AccessToken.current else { print("无法获取Facebook访问令牌") return } // 将Facebook令牌转换为Firebase凭证 let firebaseCredential = FacebookAuthProvider.credential(withAccessToken: fbToken.tokenString) // 用凭证登录Firebase Auth Auth.auth().signIn(with: firebaseCredential) { authResult, error in if let error = error { print("Firebase关联登录失败:\(error.localizedDescription)") return } // 登录成功,跳转第二个视图 guard let user = authResult?.user else { return } print("登录成功,用户邮箱:\(user.email ?? "未获取到邮箱")") // 这里执行跳转,比如用segue或者导航push self.performSegue(withIdentifier: "你的跳转标识", sender: self) } } }
二、跳转后Fetch数据提示权限拒绝的排查方案
你遇到的问题大概率是两个原因:Firebase Auth登录未完成就跳转,或者数据库安全规则配置不对,按下面的步骤排查:
1. 确认Firebase Auth是否真的登录成功
你的原代码片段只执行了Facebook登录,但没有将Facebook的令牌关联到Firebase Auth——这是关键!如果跳过这一步,Firebase会认为你没有登录,自然会触发权限拒绝。
检查你的登录代码是否包含了「用Facebook凭证登录Firebase」的步骤(就是上面代码里的Auth.auth().signIn(with: firebaseCredential)部分),这一步必须有。
2. 检查Firebase数据库/存储的安全规则
打开Firebase控制台,进入「Firestore数据库」(或者你用的实时数据库)→「规则」,确保规则允许已认证用户访问数据。比如基础的规则可以设为:
// Firestore规则示例 rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } }
如果你的数据是按用户ID分集合的(比如users/{userId}),更安全的规则是:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth.uid == userId; } } }
修改规则后记得点击「发布」生效。
3. 确保第二个视图的Fetch操作在用户登录状态稳定后执行
有时候跳转后,Firebase Auth的状态还没同步完成,第二个视图就开始Fetch了,导致获取不到当前用户。可以用状态监听器来确保用户登录后再执行查询:
// 在第二个视图的viewDidLoad里添加 override func viewDidLoad() { super.viewDidLoad() // 监听用户认证状态变化 Auth.auth().addStateDidChangeListener { auth, user in guard let currentUser = user else { // 无登录用户,跳转回登录页 print("当前未登录,权限拒绝") self.navigationController?.popViewController(animated: true) return } // 用户已登录,执行Fetch操作 self.fetchUserData(user: currentUser) } } // 封装Fetch方法 func fetchUserData(user: User) { let db = Firestore.firestore() // 这里替换成你的查询路径 db.collection("users").document(user.uid).getDocument { snapshot, error in if let error = error { print("Fetch数据出错:\(error.localizedDescription)") return } guard let data = snapshot?.data() else { print("未找到用户数据") return } // 处理获取到的数据 print("获取到数据:\(data)") } }
4. 检查Facebook测试应用的权限配置
确保你的Facebook测试应用已经启用了需要的权限,并且测试用户(你用来登录的账号)是在Facebook开发者平台的「测试用户」里添加的,这样才能正常获取权限。
内容的提问来源于stack exchange,提问作者Andres Gomez
相关产品推荐
相关产品推荐

