Как перейти на новый viewController после Аутентификации Firebase? - PullRequest
0 голосов
/ 25 апреля 2019

Я успешно реализовал предварительно построенный пользовательский интерфейс Firebase.Он включает провайдеров для Google, Facebook, электронной почты и телефона.После запуска приложения вы попадете в viewController с кнопкой входа в систему.Нажатие на кнопку вызывает authUIController.После входа в один из провайдеров authUIController исчезает, и я возвращаюсь к исходному viewController с кнопкой входа в систему.Как мне перейти на новый viewController после аутентификации.Я уверен, что это глупо просто, и я смотрю что-тоПожалуйста, помогите.

Я пытался использовать present(viewController(), animation: true, completion: nil) и performSegue(withIdentifier: "goHome", sender: nil) в нескольких местах моего кода.Я переместил массив моего провайдера с viewDidLoad() на viewDidAppear() и ничего.Я не знаю, что здесь делать.Я безуспешно искал документацию Google, YouTube и переполнение стека.Я знаю, что мне следует отправлять только фрагменты своего кода, но я так растерялся, что должен показать, что вставил код viewControllers.

import UIKit
import Firebase
import FirebaseAuth
import FirebaseUI
import FirebaseDatabase
import FacebookCore
import FacebookLogin
import FBSDKLoginKit
import FacebookShare
import GoogleSignIn

class LoginViewController: UIViewController, FUIAuthDelegate,
GIDSignInUIDelegate, FBSDKLoginButtonDelegate {

    @IBAction func loginAction(sender: AnyObject) {
        // Present the default login view controller provided by authUI
        let authViewController = authUI?.authViewController();
        self.present(authViewController!, animated: true, completion: nil)
    }

    let loginButton = FBSDKLoginButton()

    fileprivate(set) var auth:Auth?
    fileprivate(set) var authUI: FUIAuth? //only set internally but get externally
    fileprivate(set) var authStateListenerHandle: AuthStateDidChangeListenerHandle?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let accessToken = AccessToken.current {
            // User is logged in, use 'accessToken' here.
        }

        GIDSignIn.sharedInstance().uiDelegate = self
        GIDSignIn.sharedInstance().signIn()

        self.authStateListenerHandle = self.auth?.addStateDidChangeListener { (auth, user) in
            if user != nil {(self.performSegue(withIdentifier: "goHome", sender: nil))
            } else {
                self.loginAction(sender: self)
                return
            }
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        let providers: [FUIAuthProvider] = [
            FUIEmailAuth(),
            FUIGoogleAuth(),
            FUIFacebookAuth(),
            FUIPhoneAuth(authUI: FUIAuth.defaultAuthUI()!),
            ]
        //loginButton.delegate = self

        // Do any additional setup after loading the view, typically from a nib.
        self.auth = Auth.auth()
        self.authUI = FUIAuth.defaultAuthUI()
        self.authUI?.delegate = self
        self.authUI?.providers = providers
    }

    func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
        if let error = error {
            print(error.localizedDescription)
            return
        }
        let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)

        Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
            if let error = error {
                // ...
                return
            }
            // User is signed in
            // ...
        }
    }

    func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
        print("User Logged Out")
    }

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
        // ...
        if let error = error {
            // ...
            return
        }

        guard let authentication = user.authentication else { return }
        let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                       accessToken: authentication.accessToken)
        Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
            if let error = error {
                // ...
                return
            }
        }
    }

    // Implement the required protocol method for FIRAuthUIDelegate

    func authUI(_ authUI: FUIAuth, didSignInWith user: User?, error: Error?) {
        guard let authError = error else { return }

        let errorCode = UInt((authError as NSError).code)

        switch errorCode {
        case FUIAuthErrorCode.userCancelledSignIn.rawValue:
            print("User cancelled sign-in");
            break

        default:
            let detailedError = (authError as NSError).userInfo[NSUnderlyingErrorKey] ?? authError
            print("Login error: \((detailedError as! NSError).localizedDescription)");
        }
    }
}

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Не могу поверить, я понял это!Спасибо всем за помощь!Ниже был код, который у меня был (это был правильный код), но я продолжал получать сообщение об ошибке: LoginViewController: 0x104f17660>, чье представление не находится в иерархии окон!

func viewDidAppear(){
        self.authStateListenerHandle = self.auth?.addStateDidChangeListener { (auth, user) in
        if user != nil {(self.performSegue(withIdentifier: "goHome", sender: nil))
        } else {
            self.loginAction(sender: self)
            return
        }
    }
}

Я продолжал переключать вещи вокруг и вокруг... другой код, который я пробовал, был

func viewDidAppear(){
        self.authStateListenerHandle = self.auth?.addStateDidChangeListener { (auth, user) in
        if user != nil {(self.present(UIViewController(), animated: true, completion: nil))
        } else {
            self.loginAction(sender: self)
            return
        }
    }
}

Этот код не удался, независимо от того, что я пытался.Первый блок кода был правильным, моя проблема была в том, что мой сюжет раскадровки показывал (push), а не присутствовал (модально).Как только я изменил этот БАМ, это сработало.Тьфу, так просто, но безумно, чтобы понять.Еще раз спасибо за помощь, ребята!

0 голосов
/ 25 апреля 2019

Если ваш FirebaseUI вызывается правильно, вы должны обработать результат в методе, называемом didSignInWith, например:

func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?) {
  // handle user and error as necessary
}

Вы можете проверить эту ссылку на Документация Firebase

Образец:

func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?) {
    if error != nil {
        // HANDLE login
        login()
    } else {
        // HANDLE Error
    }
}

func login() {
    let authUI = FIRAuthUI.init(auth: FIRAtuth.auth()!)
    authUI?.delegate = self
    let authViewController = authUI?.authViewController()
    self.present(authViewController!, animated: true, completion: nil)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...