James
James

Reputation: 1302

Firebase authentication: linking multiple accounts in Swift

I've set up Firebase authentication for my iOS app using Facebook, Google & email/password sign in and it's all working fine. This authentication only happens when the user wants to access high-priority parts of my app (i.e. I don't require users to sign in to start using the app).

On app start up, I sign users in anonymously in the background and that's working fine too.

I've read the documentation but I'm struggling to understand the code required to enable me to link an anonymous account to a Facebook/email signed in account in the following flow:

My method currently looks like this:

func signupWithFacebook(){
    // track the anonymous user to link later
    let prevUser = FIRAuth.auth()?.currentUser

    FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self) { (result, error) in
        if let token = result?.token?.tokenString {
            let credential = FIRFacebookAuthProvider.credentialWithAccessToken(token)

            FIRAuth.auth()?.signInWithCredential(credential, completion: { (user, error) in
                if user != nil && error == nil {
                    // Success
                    self.success?(user: user!)
                    dispatch_async(dispatch_get_main_queue(), {
                        self.dismissViewControllerAnimated(true, completion: nil)
                    })

                }
            })
        }
    }
}

Any pointers to remove the confusion would be great.


UPDATE: I've realised I was confused about the app logic because of users being created during testing. Instead of 2 separate users being created for the above scenario (one authenticated via Facebook and another anonymously), all that happens is that the original anonymous user.uid "A" is "linked" to some Facebook authentication credentials. In the Firebase console this is shown by the anonymous uid changing from anonymous to one with the Facebook logo next to it.

This is what my working method looks like:

func signupWithFacebook(){
    FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self) { (result, error) in
        if let token = result?.token?.tokenString {
            let credential = FIRFacebookAuthProvider.credentialWithAccessToken(token)

            FIRAuth.auth()?.currentUser!.linkWithCredential(credential) { (user, error) in
                if user != nil && error == nil {
                    // Success
                    self.success?(user: user!)
                    dispatch_async(dispatch_get_main_queue(), {
                        self.dismissViewControllerAnimated(true, completion: nil)
                    })
                } else {
                    print("linkWithCredential error:", error)
                }
            }
        }
    }
}

Upvotes: 2

Views: 4261

Answers (1)

NSGangster
NSGangster

Reputation: 2447

So your code follows the first 2 steps in this link. But the documentation explicity says not to call signInWithCredential but instead call

FIRAuth.auth()?.currentUser.linkWithCredential(credential) { (user, error) in
  // ...
}

After getting your credential from Facebook's SDK.

Quote from link: "If the call to linkWithCredential:completion: succeeds, the user's new account can access the anonymous account's Firebase data."

Upvotes: 4

Related Questions