How can I add phone authentication in firebase using swift? - ios

So firebase recently supported phone auth, but the problem is that the documentation is in objective-c. And I have never done push notifications before. this is a link to the objc phone auth docs: https://firebase.google.com/docs/auth/ios/phone-auth

You can see an example in the official sample repo: https://github.com/firebase/quickstart-ios/blob/master/authentication/AuthenticationExampleSwift/MainViewController.swift#L161
The core process is like this:
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber) { (verificationID, error) in
if let error = error {
// TODO: show error
return
}
guard let verificationID = verificationID else { return }
verificationCode = // TODO: get SMS verification code from user.
if let verificationCode = verificationCode {
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID, verificationCode: verificationCode)
Auth.auth().signIn(with: credential) { (user, error) in
// TODO: handle sign in
}
} else {
// Verification code was empty
}
}
}
You'll need to plug in UI to prompt the user (thats in the sample), or take advantage of FirebaseUI to handle it all for you: https://github.com/firebase/FirebaseUI-iOS

Related

How to check if Google/Facebook account has already been used to create account on Firebase Auth

I am currently working on the signup/login of my app using Firebase Authentication.
I have custom buttons for Facebook Signup/Login and Google Signup/Login.
For example, the code for the Facebook Signup/Login button is
#objc private func performFacebookLogin(_ sender: UIButton) {
let fbLoginManager : LoginManager = LoginManager()
fbLoginManager.logIn(permissions: ["email"], from: self) { (result, error) -> Void in
if let error = error {
print(error)
} else {
if result == nil {
print("no result!")
return
}
if AccessToken.current == nil {
print("no token")
return
}
DispatchQueue.main.async {
ThirdPartySignupViewController.push(fromVC: self, method: .facebook)
}
}
}
}
This will take the user to another view controller to add additional information to their account if they have not yet created an account in the app using this Facebook account.
However, I can not find any way to determine whether or not the Facebook account has previously used for an account in the app, in which case I want to just log the user in and take them to the main screen. Is there a way to do this?
I have tried the signIn(with:) method, hoping that it would return an error if there is no account in the app with the credentials of this Facebook account, but this will not work because this will end up creating a new account if the Facebook account hasn't been used previously to create an account.
let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)
Auth.auth().signIn(with: credential) { (authResult, error) in
//check if I get an error if the Facebook account has not been used
}
(EDIT) The desired flow is 1.Sign in with Facebook/Google → 2.Enter additional info → 3.Create account on Firebase Authentication.
When authenticating with Firebase - the Auth object returns isNewUser through additionalUserInfo. Therefore you can see the status of a new or existing user.
let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)
Auth.auth().signIn(with: credential) { (authResult, error) in
//authResult?.additionalUserInfo?.isNewUser
if let auth = authResult{
if auth.additionalUserInfo?.isNewUser {
// User has not been authenticated before. Do what you need
} else {
// User has been authenticated before
}
}
}

Update Phone Number in Firebase Authentication - Swift

Is there a way to update the phone number in firebase auth? The thing is if the user entered a wrong number in registration then can I update the old number to new one then send the verification code in that new number? How can I achieve this?
There is a method on the User object called updatePhoneNumber, which seems to be what you want.
The documentation doesn't mention anything about what this does to the verification status, although I'd assume it indeed will require the new number to be verified too. Give it a try, and let me know if that isn't the case.
On the screen where the user has to enter their phone number:
var verificationId: String?
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumberTextField.text!, uiDelegate: nil) { (verificationID, error) in
if let error = error { return }
self.verificationId = verificationID else { return }
}
On the screen where the user has to enter the sms verification code:
guard let safeVerificationId = self.verificationId else { return }
let credential = PhoneAuthProvider.provider().credential(withVerificationID: safeVerificationId, verificationCode: smsTextField.text!)
Auth.auth().currentUser?.updatePhoneNumber(credential, completion: { (error) in
if let error = error { return }
})
You're welcome
Auth.auth().currentUser?.updatePhoneNumber(credential, completion: { (error) in
if error == nil {
print("succes")
}
})

How to implement Firebase Microsoft OAuth in iOS Swift?

I'm fairly new to Swift and Firebase and I'm trying to get the Microsoft OAuth provider working as described here:
https://firebase.google.com/docs/auth/ios/microsoft-oauth?authuser=0
My App is stable when run, but the MSLoginTapped button does nothing and when debugging I'm only able to see that provider.getCredentialWith doesn't appear to run because I do not receive my print statement.
There seemed to be multiple errors in the documentation, so I doctored it up as best possible and submitted a request for review of the documentation.
Firebase Documentation snippet:
provider.getCredentialWithUIDelegate(nil) { credential, error in
if error != nil {
// Handle error.
}
if credential != nil {
Auth().signInAndRetrieveData(with: credential) { authResult, error in
if error != nil {
// Handle error.
}
// User is signed in.
// IdP data available in authResult.additionalUserInfo.profile.
// OAuth access token can also be retrieved:
// credential.accessToken
}
}
}
Problem 1: provider.getCredentialWithUIDelegate is not recognized.
Problem 2: Auth().signInAndRetrieveData is not recognized.
========== ========== ========== ========== ==========
Here's what I'm working with (that's NOT working):
class LoginViewController: UIViewController {
var ref : DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func MSLoginTapped(_ sender: UIButton) {
let provider = OAuthProvider(providerID: "microsoft.com")
provider.getCredentialWith(nil) { (credential, error) in
if error != nil {
// Handle error.
print("Failed to retreive credential.")
return
}
if credential != nil {
Auth.auth().signInAndRetrieveData(with: credential!) { authResult, error in
if error != nil {
// Handle error.
}
// User is signed in.
// IdP data available in authResult.additionalUserInfo.profile.
// OAuth access token can also be retrieved:
// credential.accessToken
}
} else {
print("Credential is nil.")
}
}
}
}
Ran into the same problem.
let provider = OAuthProvider(providerID: "microsoft.com")
provider is a local variable, getCredentialWith is async and ARC will get rid of provider. Make it global scope.
Firebase does not show up sign page for microsoft.com in Swift / iOS

iOS: Firebase and facebook account kit login

I wanted to ask if anyone could direct me to an example or explanation of how can I add a phone login for firebase using Facebook’s Account Kit.
I am getting accessToken from facebook account kit and then try to authorize like this
fileprivate func authorizeWithAccessToken(_ accessToken: AKFAccessToken?, phoneNumber: AKFPhoneNumber?, error: NSError?) {
guard let accessToken = accessToken else {
return
}
FIRAuth.auth()?.signIn(withCustomToken: accessToken.tokenString) { (user, error) in
if (error != nil) {
print(error?.localizedDescription)
} else {
print("User logged in")
}
}
}
But I am getting error:
"The custom token format is incorrect. Please check the documentation." UserInfo={NSLocalizedDescription=The custom token format is incorrect. Please check the documentation., error_name=ERROR_INVALID_CUSTOM_TOKEN})
Here my token:
EMAWeGCejpgSijO0ncgBYl7HxLTZBy0rWrwaHihA81ZB286EEPhdZCtDSWZAnajp8pmX10E1ZCJDV7Ghwz0NrxRMhZCgSPzZC9imjbamk8bvv2AZDZD
Why are you using customTokens for Facebook authentication instead of using the built-in credentials methods Firebase has for Facebook?
Instead of the Token create a credentials object with the Facebook library:
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
and pass this object to the signIn(with: ) method.
FIRAuth.auth()?.signIn(with: credential) { (user, error) in
if let err = error {
print(err?.localizedDescription)
return
}
// Do your stuff here....
}
A full documentation of using Firebase and Facebook can be found here

Invalid API Key supplied using Firebase

I'm using Firebase Auth to allow users to sign up using Facebook. I have taken all the steps from here to implement sign up including adding GoogleService-Info.plist to my project.
I get the Facebook permission screen all fine but when the app hits
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
this error is returned: An invalid API Key was supplied in the request.
Can anyone help me with this please?
Thanks
Here is my function code to log in using Facebook.
#IBAction func signUpWithFacebook() {
let fbLogin = FBSDKLoginManager()
fbLogin.logInWithReadPermissions(["email"], fromViewController:self, handler: {
(result, error) -> Void in
if ((error) != nil) {
print("Process error")
} else if (result.isCancelled) {
print("Cancelled");
} else {
print("Logged in");
let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(accessToken)
print(FBSDKAccessToken.currentAccessToken().tokenString)
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
// ...
if let user = user{
print(user.displayName)
}
else{
if let error = error {
print(error.localizedDescription)
}
}
}
}
})
}
Solved it, for anyone that needs the solution in the future.
Sometimes API_KEY is missing from the GoogleService-Info.plist, this needs to be added.
The API Key can be found from Google API Console https://console.developers.google.com/
You can solve this by Downloading again the "GoogleService-Info.plist" file, under the Project Setting section on Firebase Console.
Ensure that the API_KEY is set on the new "GoogleService-Info.plist".

Resources