2016-09-02 19 views
4

Firebaseを使用して、最初にSignInViewControllerという名前のアプリケーションを構築しています。方法:Firebase - iOS Swift:FIRAuth.auth()。signOut()現在のユーザーをサインアウトしない

@IBAction func didTapSignIn(sender: AnyObject) { 
    let email = emailField.text 
    let password = passwordField.text 
    FIRAuth.auth()?.signInWithEmail(email!, password: password!) { (user, error) in 
     if let error = error { 
      print(error.localizedDescription) 
      return 
     } 
     self.signedIn(user!) 
    } 
} 

func signedIn(user: FIRUser?) { 
    AppState.sharedInstance.displayName = user?.displayName ?? user?.email 
    AppState.sharedInstance.signedIn = true 
    NSNotificationCenter.defaultCenter().postNotificationName(Constants.NotificationKeys.SignedIn, object: nil, userInfo: nil) 
    performSegueWithIdentifier(Constants.Segues.SignInToHome, sender: nil) 
} 

アプリが起動し、そうである場合には、標識は、ユーザのそのキャッシュされた現在のユーザが存在する場合SignInViewControllerもチェック:

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(true) 
    //Synchronously gets the cached current user, or null if there is none. 
    if let user = FirebaseConfigManager.sharedInstance.currentUser { 
     self.signedIn(user) 
    } 
} 

ユーザがログインされた後は、アプリ「」と表示され、「サインアウトナビゲーションバーの左上にあるボタンをクリックします。ユーザーが「ログアウト」ボタンをタップすると、そのユーザーがサインアウトを取得することになっていると、アプリは、以下の方法でバックSignInViewControllerにセグエ必要があります。

私は「サインアウト」ボタンをタップし

@IBAction func didTapSignOut(sender: UIBarButtonItem) { 
    print("sign out button tapped") 
    let firebaseAuth = FIRAuth.auth() 
    do { 
     try firebaseAuth?.signOut() 
     AppState.sharedInstance.signedIn = false 
     dismissViewControllerAnimated(true, completion: nil) 
    } catch let signOutError as NSError { 
     print ("Error signing out: \(signOutError)") 
    } catch { 
     print("Unknown error.") 
    } 
} 
didTapSignOutメソッドが呼び出され、実行されます。 しかし、コードの try firebaseAuth?.signOut()行が実行された後、現在のユーザーは nilである必要があります。現在のユーザーが firebaseAuth?.signOut()後にサインアウトされませんので、アプリがバックにsegues後、呼び出されます

po FIRAuth.auth()?.currentUser 
▿ Optional<FIRUser> 
    - Some : <FIRUser: 0x7fde43540f50> 

:私はXcodeのコンソールでの現在のユーザをプリントアウトするときには、現在のユーザーがまだログインしていますSignInViewControllerまだキャッシュされている現在のユーザーがいると思うので、ユーザーは再びサインインします。

これはキーチェーンの問題ですか?

NSNotificationCenter.defaultCenter().postNotificationNameと呼ばれることがありますか?私のコードはGoogleのFirebaseスウィフトコードラボから直接来て

ので、私はそれが働いていない理由はわからない: https://codelabs.developers.google.com/codelabs/firebase-ios-swift/#4

+0

http://stackoverflow.com/a/39170080/6297658 – Dravidian

+0

ありがとう@Dravidian、私は見て回ります。 – alexisSchreier

+0

@Dravidian、参考に感謝します。しかし、私がviewWillAppear(animated:Bool)メソッドでcurrentUserを印刷しようとしても、アプリケーションがサインインページに戻ると、現在のユーザーはnilではありません。 .signOut()メソッドが非同期に完了したため、viewWillAppear(animated:Bool)メソッドがそのユーザーがまだサインインしているかどうかをチェックする前に、ユーザーはサインインされていないと言いますか?もしそうなら、** signOut()メソッドが成功した場合にのみ、現在のユーザー**のチェックをどうやって実行すればよいでしょうか? – alexisSchreier

答えて

2

使用感嘆符は、疑問符ありません。

try! FIRAuth.auth()!.signOut() 
+0

答えてくれてありがとう@rMickeyD。私はまだ同じ結果を得ています。私は自分のコードを編集しようとしました! viewWillAppear(animated:Bool)が呼び出され、 'SignInViewController'でユーザをチェックすると、現在のユーザはキャッシュに残っていますが、FIRAuth.auth()!. signOut() – alexisSchreier

+0

neverアンラップ( '!')を '試行 'にすると、アンラップを強制して' signOut'にエラーが発生した場合にアプリケーションがクラッシュします。たとえば、ユーザーがインターネットに接続できない(または飛行機モードで)場合、 'signOut'は間違いなくエラーを投げます。この場合、あなたのアプリは最も確実にクラッシュします。 – Annjawn

2

あなたはそうのようなあなたのビューコントローラのごviewDidAppear方法でリスナーを追加することができます。これは、ユーザーの認証状態が変化したときにコードを実行することができます

FIRAuth.auth()?.addStateDidChangeListener { auth, user in 
    if let user = user { 
     print("User is signed in.") 
    } else { 
     print("User is signed out.") 
    } 
} 

。 FirebaseのsignOutメソッドには完了ハンドラがないので、イベントを聞くことができます。

0

私はちょうど私が同じ問題だと思うものを持っていた - Firebase +スウィフト3は、ログアウト時にstateDidChangeListenersをトリガしないだろう、まだログインしていたユーザーを考えて私のアプリを残した

を私のために働いてしまったものでした。毎回FIRAuth.auth()を呼び出すのではなく、FIRAuth.auth()インスタンスへの単一の参照を保存して再利用する必要があります。

FIRAuth.auth()?.signOut()を呼び出すと、以前に添付したstateDidChangeListenersがトリガーされません。しかし、変数を保存して両方の方法で再利用すると、期待どおりに機能しました。

2
GIDSignIn.sharedInstance().signOut() 
1

実際にこの問題も発生しました。Firebaseが提供している方法でユーザをログアウトしていましたが、コンソールに印刷したときにはまだオプションのユーザがいます。

は、私はそれは常にFirebaseが提供する認証ハンドラで構成されているように、現在のユーザーを設定するロジックを変更する必要がありました:限り、あなたは、このハンドルから現在のユーザーを参照しているよう

var currentUser: User? = Auth.auth().currentUser 
var handle: AuthStateDidChangeListenerHandle! 

init() { 

    handle = Auth.auth().addStateDidChangeListener { (auth, user) in 
     self.currentUser = user 

     if user == nil { 
      UserDefaults.standard.setValue(false, forKey: UserDefaults.loggedIn) 
     } else { 
      UserDefaults.standard.setValue(true, forKey: UserDefaults.loggedIn) 
     } 

    } 

} 

、それを認証状態に関係なく、現在のユーザーを更新します。

0

firebaseのログアウトメソッドがエラーをスローする可能性がある場合、force unwrapを使用している回答があります。こんなことしないで!

代わりにコールが何で行う必要があります - キャッチ - 。ブロック

do { 
     try Auth.auth().signOut() 
    } catch let error { 
     // handle error here 
     print("Error trying to sign out of Firebase: \(error.localizedDescription)") 
    } 

以下のようにあなたは、その後Auth.auth()を使用して状態変化を聴くことができaddStateDidChangeListenerし、それに応じて処理します。

関連する問題