我正在关注聊天应用程序上的 iOS 学院教程。在上述应用程序中,当用户第一次使用 Facebook 登录时,我需要检索相关的电子邮件并将其存储在我的数据库中。潜伏在 YT 评论(此处)中,我发现如果使用电话号码注册 FB 帐户,则它可能没有关联的电子邮件。引用文字评论:
我在没有电子邮件的情况下创建了我的 facebook 帐户(仅通过电话号码),它仍然注册身份验证,但是缺少标识符。它也不会向数据库发送信息。万一只有手机的人都试过了。
由于我需要将检索到的电子邮件传递到我的 Firebase 实时数据库,因此我想处理此问题,但如果没有关联的电子邮件,我需要知道当我尝试使用 FBSKDLoginKit API 检索电子邮件时会发生什么。
由于我的 FB 有一个关联的电子邮件,显然没有办法删除它并将该字段留空,我试图用我的电话号码注册一个新的 FB 帐户。问题是,为了能够在测试模式下运行应用程序并登录 FB,我需要在 Facebook For Developers 上对其进行验证,但要登录 Developers,我需要关联的电子邮件。所以我处于死胡同,无法测试自己。
我的问题是:如果没有关联的电子邮件,有谁知道 FB 请求中返回的电子邮件结果是什么?
这是我的代码,我的猜测是该函数在下面注释行return的guard块中命中,因为电子邮件等于 nil,但从我在 Youtube 上阅读的内容来看,似乎只有数据库块被跳过,而Firebase 身份验证成功。所以也许它返回一个空字符串或其他东西。
func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {
guard let token = result?.token?.tokenString else {
return
}
let facebookRequest = FBSDKLoginKit.GraphRequest(graphPath: "me",
parameters: ["fields" : "email, first_name"], tokenString: token,
version: nil,
httpMethod: .get)
facebookRequest.start { [weak self] _, result, error in
guard let result = (result as? [String: Any]), error == nil else {
self?.alertUserLoginError(message: "An error occurred while processing your request. Please try to sign in using Google.")
return
}
guard let firstName = (result["first_name"] as? String),
let email = (result["email"] as? String) else {
return
}
// Imo here the func returns cause email is equal to nil, but apparently that's not true.
// The database block is skipped, but the auth block down below is not.
DatabaseManager.shared.insertUser(with: chatUser, completion: { success in
// Doing other unrelated stuff
}
// The following block is run apparently, not sure why
let credential = FacebookAuthProvider.credential(withAccessToken: token)
FirebaseAuth.Auth.auth().signIn(with: credential) { authResult, error in
guard authResult != nil, error == nil else {
FBSDKLoginKit.LoginManager().logOut()
return
}
}
}
}
这是 DatabaseManager 类中的数据库函数,上面调用过:
public func insertUser(with user: ChatAppUser, completion: @escaping (Bool) -> Void) {
database.child(user.safeEmail).setValue([
"first_name" : user.firstName
],
withCompletionBlock: { error, _ in
guard error == nil else {
completion(false)
return
}
completion(true)
})
}