ユーザーがすでにFirebaseにログインしているかどうかを検出するにはどうすればよいですか?


102

Googleログイン用のJavaScriptファイルでFirebaseノードAPIを使用しています。

firebase.initializeApp(config);
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);

これは正常に機能し、ユーザーは自分のGoogle認証情報でログインできます。ユーザーが再度ページにアクセスすると、ポップアップが再び開きますが、ユーザーはすでにログインしているため、ユーザーの操作を必要とせずにポップアップが閉じます。ポップアップを要求する前に、すでにログインしているユーザーがいるかどうかを確認する方法はありますか?

回答:


113

https://firebase.google.com/docs/auth/web/manage-users

認証状態変更オブザーバーを追加する必要があります。

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

3
これは私には矛盾しています。stackoverflow.com/questions/39395158/...
ダンP.

2
onAuthStateChangedを使用して、ユーザーが新しいかどうかを確認する方法はありますか?
ブレナン

はい、ただしを介してではありませんonAuthStateChanged。これは4.6.0で追加されました:firebase.google.com/support/release-notes/js#4.6.0あなたがサインイン法やからからそれを得ることができますcurrentUser.metadata(時間と作成時間の最後の記号)...
bojeil 2017年

@bojeilこの方法には注意点があると思います。このコードを1つのページに配置すると、そのページにいない場合でもトリガーされます。AuthStateが変更されるとトリガーされます。他のページで変更された場合、必要のないときに効果的にトリガーされます。少なくとも、それが今私に起こっていることです。
thevengefulco 2017

1
これにより、他のタブのサインインイベントが検出されます。意図したとおりに機能します。Firebase Authは、ログインイベントをウィンドウ全体に伝達します。
bojeil 2017年

82

currentUserがあるかどうかを確認することもできます

var user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}

8
これは、すぐにログインした後でもnullを返します。
アーモラ2017

8
それは奇妙なことです。私にとってはうまくいきます。おそらく問題は、認証が非同期であり、_ currentUser_がまだ更新されていないためです。
Daniel Passos

1
ドキュメントから:authオブジェクトが初期化を完了していないため、currentUserもnullになる可能性があります。オブザーバーを使用してユーザーのサインインステータスを追跡する場合は、このケースを処理する必要はありません。
cheshireoctopus 2017年

あなたはそれに頼ることはできません。公式ドキュメントを参照してください:「getCurrentUserがnull以外の値を返す場合があります...」
Andrew

nullを取得する場合は、おそらくまだ初期化されていないことが原因です。
Arnaldo Capo

28

ページの読み込みが開始されたときにユーザー署名れるかどうかを判断することはできませんが、回避策があります。

あなたはできる最後の認証状態を記憶セッション間とタブの間、それを永続化するのlocalStorageに。

次に、ページの読み込みが開始されると、楽観的にユーザーが自動的に再サインインすると想定し、確認できるまで(つまり、onAuthStateChanged発砲後)ダイアログを延期できます。それ以外の場合、localStorageキーが空の場合は、ダイアログをすぐに表示できます。

firebase onAuthStateChangedイベントは、ページが読み込まれてから約2秒後に発生します。

// User signed out in previous session, show dialog immediately because there will be no auto-login
if (!localStorage.getItem('myPage.expectSignIn')) showDialog() // or redirect to sign-in page

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User just signed in, we should not display dialog next time because of firebase auto-login
    localStorage.setItem('myPage.expectSignIn', '1')
  } else {
    // User just signed-out or auto-login failed, we will show sign-in form immediately the next time he loads the page
    localStorage.removeItem('myPage.expectSignIn')

    // Here implement logic to trigger the login dialog or redirect to sign-in page, if necessary. Don't redirect if dialog is already visible.
    // e.g. showDialog()
  }
})



私はこれをReactreact-routerで使用しています。上記のコードをcomponentDidMountAppルートコンポーネントに追加しました。そこには、レンダリングで、いくつかありますPrivateRoutes

<Router>
  <Switch>
    <PrivateRoute
      exact path={routes.DASHBOARD}
      component={pages.Dashboard}
    />
...

そして、これが私のPrivateRouteの実装方法です。

export default function PrivateRoute(props) {
  return firebase.auth().currentUser != null
    ? <Route {...props}/>
    : localStorage.getItem('myPage.expectSignIn')
      // if user is expected to sign in automatically, display Spinner, otherwise redirect to login page.
      ? <Spinner centered size={400}/>
      : (
        <>
          Redirecting to sign in page.
          { location.replace(`/login?from=${props.path}`) }
        </>
      )
}

    // Using router Redirect instead of location.replace
    // <Redirect
    //   from={props.path}
    //   to={{pathname: routes.SIGN_IN, state: {from: props.path}}}
    // />

あなたはこれで私を助けることができると思いますか?回答の上部にある自動ログインリダイレクトを試しましたが、削除できないようです。ローカルストレージを完全にクリアしましたが、リダイレクトが頻繁に発生するため、ログアウトしたFirebaseサイトにアクセスできません。
hego64

@ hego64実際にFirebaseアプリからログアウトしましたか?このソリューションでは、ログインは行われません。ユーザーが前のセッションでサインアウトしなかった場合にのみ、サインインフォームをスキップできます。/編集:あなたはリダイレクトループにいますか?回答を更新します。
Qwerty、

はい、もっとはっきりしているはずですが、リダイレクトループに陥っていました。ログアウトすると、アプリに戻る代わりに、サインインページに直接戻りました。以前のデプロイにロールバックすることで修正できましたが、それ以外は問題を修正するために何をすべきかわかりませんでした。
hego64

1
@ hego64サインインしていないユーザーは自由に歩き回ることができないため、ログインページへのリダイレクトは正しいですが、認証なしで使用できるルートがある場合は、ロジックをルーターに移動する必要がありますまたは、代わりに特定のルート。PrivateRouteラッパーの例のように。したがって、ユーザーが制限されたページにいてサインアウトすると、ユーザーはログインページにリダイレクトされます。他のルートには、このロジックが実装されていません。
Qwerty

私はこれに少しこだわっていました...この方法はかなりうまくいきます。ありがとうございました。
spetz83

17

このシナリオでは、onAuthStateChanged()関数を使用する必要はありません。

次のコマンドを実行すると、ユーザーがログインしているかどうかを簡単に検出できます。

var user = firebase.auth().currentUser;

「nullを返す」問題に直面している人にとっては、Firebaseの呼び出しが完了するのを待っていないからです。

ページAでログインアクションを実行してからページBを呼び出したとします。ページBで、次のJSコードを呼び出して、予想される動作をテストできます。

  var config = {
    apiKey: "....",
    authDomain: "...",
    databaseURL: "...",
    projectId: "..",
    storageBucket: "..",
    messagingSenderId: ".."
  };
  firebase.initializeApp(config);

    $( document ).ready(function() {
        console.log( "testing.." );
        var user = firebase.auth().currentUser;
        console.log(user);
    });

ユーザーがログインしている場合、「var user」には予期されるJSONペイロードが含まれます。含まれていない場合は、単に「null」になります。

そして、それだけで十分です。

よろしく


3
@マウリシオ・シルヴェストレ?使用firebase.auth.currentUser。リターンをに署名したときに正しい結果を返す私はに署名していたか否か未定義のみAUTH()。
tsujp

5

もう1つの方法は、firebaseと同じものを使用することです。

たとえば、ユーザーがログインすると、firebaseは以下の詳細をローカルストレージに保存します。ユーザーがページに戻ると、firebaseは同じメソッドを使用して、ユーザーが自動的にログインする必要があるかどうかを識別します。

ここに画像の説明を入力してください

ATTN:これは、firebaseによってリストにも推奨にもされていません。このメソッドを非公式な方法で呼び出すことができます。つまり、後でfirebaseが内部の動作を変更した場合、このメソッドは機能しない可能性があります。または要するに。自己責任!:)


5

これは機能します:

async function IsLoggedIn(): Promise<boolean> {
  try {
    await new Promise((resolve, reject) =>
      app.auth().onAuthStateChanged(
        user => {
          if (user) {
            // User is signed in.
            resolve(user)
          } else {
            // No user is signed in.
            reject('no user logged in')
          }
        },
        // Prevent console error
        error => reject(error)
      )
    )
    return true
  } catch (error) {
    return false
  }
}

1

匿名ユーザーとメールでログインしたユーザーを許可する場合はfirebase.auth().currentUser.isAnonymoustrueまたはを返すことができますfalse



-3

最初に以下をインポートします

import Firebase
import FirebaseAuth

その後

    // Check if logged in
    if (Auth.auth().currentUser != null) {
      // User is logged in   
    }else{
      // User is not logged in
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.