我遇到的问题是,以前通过 Google 登录或我的应用程序上的电子邮件注册的用户无法使用 Apple Sign In 登录到同一帐户(即使未隐藏电子邮件)。
即使身份验证令牌是分开处理的,Apple 和 Google/Firebase,我们的用户集合中的同一电子邮件也无法合并(保留现有用户帐户并为现有帐户使用新令牌)。这会产生 2 个帐户:现有帐户和新帐户,这与新的 Apple 登录存在问题。
有没有人在他们的 iOS 应用程序中遇到过这个问题,并且随着即将到来的春季 Apple 登录要求,他们如何处理 2 个令牌并合并新旧帐户?
import UIKit
import Firebase
import FirebaseAuth
import Pages
import GoogleSignIn
import AuthenticationServices
class FireAuthUserInfo {
var firstName:String?
var lastName:String?
var email:String?
init(googleUser:GIDGoogleUser) {
self.firstName = googleUser.profile.givenName
self.lastName = googleUser.profile.familyName
}
@available(iOS 13.0, *)
init(credential:ASAuthorizationCredential) {
switch credential {
case let appleIDCredential as ASAuthorizationAppleIDCredential:
default:
break
}
}
}
class UserManager: NSObject {
static let shared = UserManager()
func signInWithGoogle (user: GIDGoogleUser) {
let authentication = user.authentication
let credential = GoogleAuthProvider.credential(withIDToken: (authentication?.idToken)!,
accessToken: (authentication?.accessToken)!)
let userInfo = FireAuthUserInfo(googleUser: user)
self.authInFirebase(with: credential, user: userInfo)
}
@available(iOS 13.0, *)
func signInWithApple (with credential:AuthCredential, appleUser:ASAuthorizationCredential) {
let userInfo = FireAuthUserInfo(credential: appleUser)
self.authInFirebase(with: credential, user: userInfo)
}
func authInFirebase(with credential:AuthCredential, user:FireAuthUserInfo? = nil) {
Utility.showProgress("")
Auth.auth().signIn(with: credential) { (authResult, error) in
guard error == nil else { Utility.dismissProgress(); return}
guard let authResult = authResult else { Utility.dismissProgress(); return}
// User is signed in
let refCollection = Constants.db.databaseProfile
var query = refCollection.whereField("UserID", isEqualTo: authResult.user.uid)
if let user = user, let email = user.email {
query = refCollection.whereField("email", isEqualTo: email)
}
query.getDocuments(completion: { (snapShot, error) in
Utility.dismissProgress()
guard error == nil else { return}
if snapShot == nil || snapShot!.isEmpty == true {
let userObject = User()
userObject.uid = authResult.user.uid
userObject.email = authResult.user.email
if let user = user {
userObject.firstName = user.firstName
userObject.lastName = user.lastName
if let email = user.email {
userObject.email = email
}
}
self.saveProfile(user: userObject)
//self.gotoFillDetails(page: 3)
self.goToOnBoardingScreens()
}else {
for rest in snapShot!.documents {
let restDict = rest.data()
guard !(restDict.isEmpty) else {
continue
}
let userData = User.getInstanceFrom(dictionary: restDict)!
if let user = user, let email = user.email {
userData.email = email
}
UserDefaultHelper.saveUser(user: userData)
AppData.sharedInstance.user = userData
AppData.getAllJournalEntries()
break
}
self.gotoMain()
}
})
}
}
func saveProfile(user : User) {
let autoKey = User.getNewKey()
// let autoKey = Constants.refs.databaseProfile.childByAutoId().key
let newProfile = [
"UserID": user.uid ?? "",
"Email": user.email ?? "",
"FirstName": user.firstName ?? "",
"LastName": user.lastName ?? "",
"Gender": "",
"BirthDate": Date(),
"JobTitle": "",
"Location": "",
"TellMeMore": "",
"Referral": "",
"Last_Login": Date(),
"CreatedAt": Date(),
"UpdatedAt": Date(),
"ProfileImage": "",
"Key": autoKey,
"DeviceToken": AppData.sharedInstance.deviceToken ?? "",
"FcmToken": AppData.sharedInstance.fcmToken ?? "",
] as [String : Any]
let user = User.getInstanceFrom(dictionary: newProfile)
user?.saveToFirebase()
UserDefaultHelper.saveUser(user: user!)
AppData.sharedInstance.user = user
}
我已经能够在 Apple 测试应用程序中重现这些结果:https ://developer.apple.com/documentation/authenticationservices/implementing_user_authentication_with_sign_in_with_apple 。当用户当时使用 Apple 登录并共享她的电子邮件地址时,我能够接收用户的电子邮件,但是当用户尝试再次登录时,我无法接收该电子邮件。似乎是苹果的疏忽?