iOS firebase: FIRAuthUIDelegate.authUI not being called
I think your problem lies here, in the - (void)signInWithProviderUI:(id<FIRAuthProviderUI>)providerUI
method.
The delegate method is called in the dismissViewControllerAnimated:completion:
completion block.
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:user error:error];
}];
As you can see from the Apple docs, this method is expected to be called on a modally presented viewController. You are displaying it as a root view controller. Try displaying it with a modal from a UIViewController
, and things should work out. To debug this try and set a breakpoint at line 193 to see that it won't get hit. I would be very surprised if this doesn't work when you display the authController modally.
To come up with a possible solution to your problem (I am assuming you want to ensure a user is signed in before using your app). The below is a simplification of what I am using in an app currently.
EDIT: Updated for the new 1.0.0 FirebaseUI syntax.
class MainTabController: UITabBarController, FIRAuthUIDelegate {
let authUI: FUIAuth? = FUIAuth.defaultAuthUI()
override func viewDidLoad() {
super.viewDidLoad()
var authProviders = [FUIFacebookAuth(), FUIGoogleAuth()]
authUI.delegate = self
authUI.providers = authProviders
//I use this method for signing out when I'm developing
//try! FIRAuth.auth()?.signOut()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !isUserSignedIn() {
showLoginView()
}
}
private func isUserSignedIn() -> Bool {
guard FIRAuth.auth()?.currentUser != nil else { return false }
return true
}
private func showLoginView() {
if let authVC = FUIAuth.defaultAuthUI()?.authViewController() {
present(authVC, animated: true, completion: nil)
}
}
func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?) {
guard let user = user else {
print(error)
return
}
...
}
How to use FirebaseUI for Google authentication on iOS in Swift?
I haven't tried this solution but this StackOverflow problem was linked to the FirebaseUI repo's issues section and someone there responded;
Obj-C:
"There's a bug that prevents [[FIRAuthUI authUI] authViewController]
from being used as the root view controller of your app. The workaround is to use a placeholder view controller as your app's root view controller, then present [[FIRAuthUI authUI] authViewController]
on top of it."
for Swift users:
There's a bug that prevents FIRAuthUI.authUI().authViewController()
from being used as the root view controller of your app. The workaround is to use a placeholder view controller as your app's root view controller, then present FIRAuthUI.authUI().authViewController()
on top of it.
Link: https://github.com/firebase/FirebaseUI-iOS/issues/65
Trying to connect Facebook login via FirebaseUI Auth but having an issue with authUI.delegate = self
I'm also not familiar with FirebaseUI but here is a working example of authorizing a user with Facebook using regular Firebase and the FBSDKs
@IBAction func fbButtonTapped(sender: UIButton) {
let facebookReadPermissions = ["email", "public_profile", "user_photos"]
FBSDKLoginManager().logInWithReadPermissions(facebookReadPermissions, fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult?, error:NSError?) -> Void in
if error != nil {
Helper.displayAlert("Error Logging into Facebook", message: error!.localizedDescription, viewController: self)
} else {
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
if error != nil {
Helper.displayAlert("Error Logging into Facebook", message: error!.localizedDescription, viewController: self)
} else {
let request = FBSDKGraphRequest(graphPath:"me", parameters: ["fields": "id, first_name, last_name, email, age_range, gender, verified, timezone, picture"])
request.startWithCompletionHandler {
(connection, result, error) in
if error != nil {
print (error)
} else if let userData = result as? [String : AnyObject] {
guard let userID = FIRAuth.auth()?.currentUser?.uid else { return }
let userInfo = ["firstName": userData["first_name"] as! String, "lastName": userData["last_name"] as! String, "email": userData["email"] as! String,
"gender": userData["gender"] as! String, "id": userData["id"] as! String, "verified": userData["verified"]?.description as! AnyObject, "key": userID]
FirebaseData.fbData.createFirebaseUser(userID, user: userInfo)
self.performSegueWithIdentifier(self.loginSucessIdentifier, sender: nil)
}
}
}
}
}
})
}
func createFirebaseUser(uid: String, user: [String : AnyObject]) {
REF_USERS.child(uid).setValue(user)
}
The code could be cleaned up a bit to get rid of all the if let statements but it should get you going with a working authorization for facebook login.
What Is the Code to Install FirebaseUI on iOS (Swift)
I finally figured out how to do this! I created a video and GIST to show how to do it, but I'll try to present it here as well.
First, I updated Xcode to version 8 by clicking "Apple App Store," finding Xcode, and clicking "Update." This took awhile to download.
Second, I updated AppDelegate.swift by adding FIRApp.configure()
in the "didFinishLaunchingWithOptions" function.
Third, I added the following code to my AppDelegate.swift file:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
return handled || GIDSignIn.sharedInstance().handle(
url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
Fourth, I updated my ViewController.swift file to this (make sure to put your own Facebook secret):
// ViewController.swift
// Bizzy Books
//
// Created by Brad Caldwell on 9/23/16.
// Copyright © 2016 Caldwell Contracting LLC. All rights reserved.
//
import UIKit
import Firebase
import FirebaseAuthUI
import FirebaseDatabaseUI
import FirebaseGoogleAuthUI
import FirebaseFacebookAuthUI
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController, FIRAuthUIDelegate {
//var db = FIRDatabaseReference.init()
var kFacebookAppID = "PLACE YOUR 16-DIGIT FACEBOOK SECRET HERE (FOUND IN FIREBASE CONSOLE UNDER AUTHENTICATION)"
override func viewDidLoad() {
super.viewDidLoad()
//FIRApp.configure()
checkLoggedIn()
}
func checkLoggedIn() {
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if user != nil {
// User is signed in.
} else {
// No user is signed in.
self.login()
}
}
}
func login() {
let authUI = FIRAuthUI.init(auth: FIRAuth.auth()!)
let options = FIRApp.defaultApp()?.options
let clientId = options?.clientID
let googleProvider = FIRGoogleAuthUI(clientID: clientId!)
let facebookProvider = FIRFacebookAuthUI(appID: kFacebookAppID)
authUI?.delegate = self
authUI?.providers = [googleProvider, facebookProvider]
let authViewController = authUI?.authViewController()
self.present(authViewController!, animated: true, completion: nil)
}
@IBAction func logoutUser(_ sender: AnyObject) {
try! FIRAuth.auth()!.signOut()
}
func authUI(_ authUI: FIRAuthUI, didSignInWith user: FIRUser?, error: Error?) {
if error != nil {
//Problem signing in
login()
}else {
//User is in! Here is where we code after signing in
}
}
func application(app: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionUniversalLinksOnly] as! String
return FIRAuthUI.default()!.handleOpen(url as URL, sourceApplication: sourceApplication )
}
}
Fifth, I added a couple chunks of code to my Info.plist (you need to customize the Facebook and Google codes - see Jacob Sikorski's guide for more info on this.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.PLACE YOUR LONG CODE HERE ***(mine is 12 digits followed by a dash followed by 32 alpha-numeric characters)***</string>
<string>PLACE YOUR FACEBOOK CODE HERE ***(mine said fb followed by 16 numbers)***</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fbapi20130214</string>
<string>fbapi20130410</string>
<string>fbapi20130702</string>
<string>fbapi20131010</string>
<string>fbapi20131219</string>
<string>fbapi20140410</string>
<string>fbapi20140116</string>
<string>fbapi20150313</string>
<string>fbapi20150629</string>
<string>fbapi20160328</string>
<string>fbauth</string>
<string>fbauth2</string>
<string>fb-messenger-api20140430</string>
</array>
That should be it. Let me know if you have any questions!
Adding Background image to Firebase SignIn Screen in xCode 9.2
This is what you want to do.
Create an extension of their baseViewController
extension FUIAuthBaseViewController {
Inside of that extension, override their viewWillAppear()
and set the image there
open override func viewWillAppear(_ animated: Bool) {
self.navigationItem.leftBarButtonItem = nil
self.view.backgroundColor = .white
// if view is base view add logo as subview
let vc = self.navigationController?.viewControllers.first
if vc == self.navigationController?.visibleViewController {
makeLogoImage()
} else {
// hide the image in proceeding views by covering it with a white background
vc?.view.backgroundColor = .white
}
}
/**
Create imageView and display it at the top of the screen.
*/
func makeLogoImage() {
let imageView = UIImageView(image: UIImage(named: "angel.png"))
let width = view.frame.width
let height = view.frame.height
imageView.frame = CGRect(x: width / 4, y: height / 8 , width: width / 2, height: width / 2)
imageView.contentMode = .scaleAspectFill
self.view.addSubview(imageView)
self.view.sendSubview(toBack: imageView)
}
Related Topics
Cannot Use Tabview on Swiftui, Watchos
Split String by Components and Keep Components in Place
Split Paragraphs into Sentences
Crop/Mask Circular Image Node in Sprite Kit Gives Jagged Edges
Openinmapswithlaunchoptions Not Working
Using "Codable" to Set Property Values Doesn't Work Through Inheritance
Alternative to Switch Statement in Swiftui Viewbuilder Block
Sharing File Data Between Applications in Swift/Ios
Disable Bounce Scrolling for Wkwebview in MACos
How to Detect the 2D Images Using Arkit and Realitykit
Get Compiler Error in Swift Indexof()
Why Upload Alamofire Background Request Don't Executes in Background
Swift MAC App, Run Terminal Command Without Knowing the Path (So It Looks in Every Path in $Path)
Swift: Label Text --> "Fatal Error: Unexpectedly Found Nil While Unwrapping an Optional Value"