既存のユーザー アカウントに認証プロバイダの認証情報をリンクすることで、ユーザーが複数の認証プロバイダを使用してアプリにログインできるようになります。ログインに使用した認証プロバイダに関係なく、同じ Firebase ユーザー ID でユーザーを識別できます。たとえば、パスワードを使用してログインしたユーザーが認証情報を Google アカウントにリンクすれば、それ以降はどちらの方法でもログインできるようになります。また、匿名ユーザーが認証情報を Facebook アカウントにリンクすると、それ以降は Facebook にログインしてアプリを使用できるようになります。
準備
アプリに複数の認証プロバイダ(匿名認証も含む)のサポートを追加します。
ユーザー アカウントにフェデレーション認証プロバイダの認証情報をリンクする
既存のユーザー アカウントに Google や Facebook などの認証プロバイダからの認証情報をリンクするには、以下の手順を行います。
- 任意の認証プロバイダや認証方法を使用してユーザーのログインを行います。
- ユーザーのアカウントにリンクするプロバイダに対応する
AuthProvider
オブジェクトを取得します。例:var googleProvider = new firebase.auth.GoogleAuthProvider(); var facebookProvider = new firebase.auth.FacebookAuthProvider(); var twitterProvider = new firebase.auth.TwitterAuthProvider(); var githubProvider = new firebase.auth.GithubAuthProvider();
- リンク先となるプロバイダにログインするようユーザーに促します。ポップアップ ウィンドウをユーザーに表示するか、プロバイダのログインページにリダイレクトすることにより、ログインを促すことができます。モバイル デバイスではリダイレクトすることをおすすめします。
- ポップアップ ウィンドウでログインを行う場合は、
linkWithPopup
を呼び出します。auth.currentUser.linkWithPopup(provider).then((result) => { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });
- プロバイダのログインページにリダイレクトしてログインを行う場合は、
linkWithRedirect
を呼び出します。auth.currentUser.linkWithRedirect(provider) .then(/* ... */) .catch(/* ... */);
ユーザーがログインしたら、元のページにリダイレクトされます。元のページが読み込まれるときにgetRedirectResult
を呼び出すと、ログイン結果を取得できます。auth.getRedirectResult().then((result) => { if (result.credential) { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... } }).catch((error) => { // Handle Errors here. // ... });
認証情報がすでに別のユーザー アカウントにリンクされている場合は、アカウントのリンク付けが失敗します。この場合は、アプリに適した方法でアカウントと関連データの統合を行う必要があります。
// The implementation of how you store your user data depends on your application var repo = new MyUserDataRepo(); // Get reference to the currently signed-in user var prevUser = auth.currentUser; // Get the data which you will want to merge. This should be done now // while the app is still signed in as this user. var prevUserData = repo.get(prevUser); // Delete the user's data now, we will restore it if the merge fails repo.delete(prevUser); // Sign in user with the account you want to link to auth.signInWithCredential(newCredential).then((result) => { console.log("Sign In Success", result); var currentUser = result.user; var currentUserData = repo.get(currentUser); // Merge prevUser and currentUser data stored in Firebase. // Note: How you handle this is specific to your application var mergedData = repo.merge(prevUserData, currentUserData); return prevUser.linkWithCredential(result.credential) .then((linkResult) => { // Sign in with the newly linked credential return auth.signInWithCredential(linkResult.credential); }) .then((signInResult) => { // Save the merged data to the new user repo.set(signInResult.user, mergedData); }); }).catch((error) => { // If there are errors we want to undo the data merge/deletion console.log("Sign In Error", error); repo.set(prevUser, prevUserData); });
- ポップアップ ウィンドウでログインを行う場合は、
ユーザー アカウントにメールアドレスとパスワードの認証情報をリンクする
既存のユーザー アカウントにメールアドレスとパスワードの認証情報をリンクするには、以下の手順を行います。
- 任意の認証プロバイダや認証方法を使用してユーザーのログインを行います。
- ユーザーにメールアドレスと新しいパスワードの入力を促します。
- そのメールアドレスとパスワードを使って
AuthCredential
オブジェクトを作成します。var credential = firebase.auth.EmailAuthProvider.credential(email, password);
ログイン ユーザーの
linkWithCredential
メソッドにAuthCredential
オブジェクトを渡します。auth.currentUser.linkWithCredential(credential) .then((usercred) => { var user = usercred.user; console.log("Account linking success", user); }).catch((error) => { console.log("Account linking error", error); });
認証情報が別のユーザー アカウントにすでにリンクされている場合は、
linkWithCredential
の呼び出しが失敗します。その場合、アプリに適した方法でアカウントと関連データの統合を行う必要があります(上記の例を参照)。
ユーザー アカウントから認証プロバイダのリンクを解除する
アカウントから認証プロバイダのリンクを解除することで、ユーザーがそのプロバイダを使用してログインできなくなります。
ユーザー アカウントから認証プロバイダのリンクを解除するには、プロバイダ ID を unlink
メソッドに渡します。ユーザーにリンクされている認証プロバイダのプロバイダ ID は providerData
プロパティから取得できます。
user.unlink(providerId).then(() => { // Auth provider unlinked from account // ... }).catch((error) => { // An error happened // ... });