25
votes

I'm using the following code, to detect auth provider and log out properly

static func logOut() {
    let auth = FIRAuth.auth()!
    let provider = auth.currentUser?.providerID
    switch provider! {
        case "Facebook": FBSDKLoginManager().logOut()
        case "Google": GIDSignIn.sharedInstance().signOut()
        case "Twitter": Twitter.sharedInstance().sessionStore.logOutUserID(TWTRAPIClient.withCurrentUser().userID!)
        default:
            print("Unknown provider ID: \(provider!)")
            return
    }
    try! auth.signOut()
}

But the provider is always "Firebase". What am I doing wrong? 0_o Once that code throw "Facebook" when I was logged in twitter. Thanks in advance

UPD: Yeah, I actually can store auth provider in UserDefaults, but maybe it's Firebase bug. I'm using Firebase SDK 3.5.2

6
didn't FIRAuth.auth()!.signOut() work out? - rootcoder
@KhanXc works, but I thought it's not enough. In Android it will lead to case, where you choose different google account - Dima Rostopira
But why I can't get provider? If I will need it in any case. It is a bug, or I'm doing something wrong - Dima Rostopira

6 Answers

39
votes

Since a user can sign into their Firebase Authentication account with multiple providers, the top-level provider ID will now (usually) be Firebase.

But the currentUser has a providerData property that provides information on the speciic providers. Looping over FIRAuth.auth()!.currentUser.providerData will give you the FIRUserInfo.providerID you're looking for.

See also this question about UIDs, which are in a similar situation: Firebase returns multiple IDs, Which is unique one?

14
votes

Swift 4 solution:

   if let providerData = Auth.auth().currentUser?.providerData {
        for userInfo in providerData {
            switch userInfo.providerID {
            case "facebook.com":
                print("user is signed in with facebook")
            case "google.com":
                print("user is signed in with google")
            default:
                print("user is signed in with \(userInfo.providerID)")
            }
        }
    }
6
votes

I had to JSON.stringify(currentUser.providerData) in order to see how it's organized:

Stringify result

And i finally found the Auth Provider like this:

currentUser.providerData[0].providerId

Cheers, gl with your code : )

4
votes

Using currentUser.providerData gives you the array of providers with each provider having its own uid. The list is sorted by the most recent provider used to sign in. So the first element in currentUser.providerData is the method that the user used to sign in. So currentUser.providerData[0].providerId will give you the method that the user used to sign in.

1
votes
// Provider Type
        struct AuthProviders {
        static let phone = "phone"
        static let facebook = "facebook.com"
        static let google = "google.com"
        static let apple = "apple.com"
    }


let providerIds = auth.currentUser?.providerData.map { $0.providerID }
0
votes

To logout there is a simpler method:

let authUI = FUIAuth.defaultAuthUI()
do {
    try authUI?.signOut()
} catch let err {
    print(err);
}

On the other hand, if you want to find the provider AND determine if the user is logged in via that provider, check the accessToken. To get the accessToken you need the specific provider instance you provided to providers.

I find this is best achieved by first declaring your providers in your class this way:

lazy var facebookProvider = FUIFacebookAuth()
lazy var googleProvider = FUIGoogleAuth()

Then when you provide the providers:

let providers: [FUIAuthProvider] = [ facebookProvider, googleProvider ]

When you want the specific provider data:

if let providerData = Auth.auth().currentUser?.providerData {
    for userInfo in providerData {
        switch userInfo.providerID {
        case "facebook.com":
            if !facebookProvider.accessToken.isEmpty {
                print("user is signed in with facebook")
            }
        case "google.com":
            if !googleProvider.accessToken.isEmpty {
                 print("user is signed in with google")
            }
        default:
            print("user is signed in with \(userInfo.providerID)")
        }
    }
}

Otherwise you will get info on each provider regardless of whether the user is actually logged in.