Menautkan Beberapa Penyedia Autentikasi ke Satu Akun Menggunakan JavaScript

Anda dapat mengizinkan pengguna untuk login ke aplikasi Anda menggunakan beberapa penyedia autentikasi, dengan menautkan kredensial penyedia autentikasi ke akun pengguna yang ada. Pengguna bisa diidentifikasi dengan ID pengguna Firebase yang sama, apa pun penyedia autentikasi yang digunakan untuk login. Misalnya, pengguna yang login dengan sandi bisa menautkan Akun Google dan login dengan salah satu metode tersebut di lain waktu. Atau, seorang pengguna anonim bisa menautkan akun Facebook, kemudian login dengan Facebook untuk melanjutkan penggunaan aplikasi Anda.

Sebelum memulai

Tambahkan dukungan untuk dua penyedia autentikasi atau lebih (mungkin juga termasuk autentikasi anonim) ke aplikasi Anda.

Untuk menautkan kredensial dari penyedia autentikasi seperti Google atau Facebook ke akun pengguna yang ada:

  1. Proses login pengguna menggunakan penyedia atau metode autentikasi apa pun.
  2. Dapatkan objek AuthProvider yang sesuai dengan penyedia yang ingin Anda tautkan dengan akun pengguna. Contoh:

    API modular web

    import { GoogleAuthProvider, FacebookAuthProvider, TwitterAuthProvider, GithubAuthProvider } from "firebase/auth";
    
    const googleProvider = new GoogleAuthProvider();
    const facebookProvider = new FacebookAuthProvider();
    const twitterProvider = new TwitterAuthProvider();
    const githubProvider = new GithubAuthProvider();

    API dengan namespace web

    var googleProvider = new firebase.auth.GoogleAuthProvider();
    var facebookProvider = new firebase.auth.FacebookAuthProvider();
    var twitterProvider = new firebase.auth.TwitterAuthProvider();
    var githubProvider = new firebase.auth.GithubAuthProvider();
  3. Mintalah pengguna untuk login dengan penyedia yang ingin Anda tautkan. Anda dapat meminta pengguna untuk login, baik dengan membuka jendela pop-up maupun dengan mengalihkannya ke halaman login penyedia. Untuk perangkat seluler, sebaiknya gunakan metode pengalihan.
    • Untuk login dengan jendela pop-up, panggil linkWithPopup:

      API modular web

      import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
      const provider = new GoogleAuthProvider();
      
      const auth = getAuth();
      linkWithPopup(auth.currentUser, provider).then((result) => {
        // Accounts successfully linked.
        const credential = GoogleAuthProvider.credentialFromResult(result);
        const user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });

      API dengan namespace web

      auth.currentUser.linkWithPopup(provider).then((result) => {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    • Untuk login dengan mengalihkan pengguna ke halaman login penyedia, panggil linkWithRedirect: Ikuti praktik terbaik saat menggunakan `linkWithRedirect`.

      API modular web

      import { getAuth, linkWithRedirect, GoogleAuthProvider } from "firebase/auth";
      const provider = new GoogleAuthProvider();
      
      const auth = getAuth();
      linkWithRedirect(auth.currentUser, provider)
        .then(/* ... */)
        .catch(/* ... */);

      API dengan namespace web

      auth.currentUser.linkWithRedirect(provider)
        .then(/* ... */)
        .catch(/* ... */);
      Setelah login, pengguna akan diarahkan kembali ke halaman Anda. Kemudian, Anda dapat mengambil hasil login dengan memanggil getRedirectResult saat halaman Anda dimuat.

      API modular web

      import { getRedirectResult } from "firebase/auth";
      getRedirectResult(auth).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        if (credential) {
          // Accounts successfully linked.
          const user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });

      API dengan namespace web

      auth.getRedirectResult().then((result) => {
        if (result.credential) {
          // Accounts successfully linked.
          var credential = result.credential;
          var user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    Jika pengguna berhasil login, akun pengguna dengan penyedia tersebut akan ditautkan dengan akun pengguna di project Firebase Anda.

    Penautan akun akan gagal jika kredensial sudah ditautkan ke akun pengguna lain. Dalam situasi ini, Anda harus menangani penggabungan akun dan data terkait dengan cara yang sesuai untuk aplikasi Anda:

    API modular web

    import { getAuth, signInWithCredential, linkWithCredential, OAuthProvider } from "firebase/auth";
    
    // The implementation of how you store your user data depends on your application
    const repo = new MyUserDataRepo();
    
    // Get reference to the currently signed-in user
    const auth = getAuth();
    const 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.
    const 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
    signInWithCredential(auth, newCredential).then((result) => {
      console.log("Sign In Success", result);
      const currentUser = result.user;
      const currentUserData = repo.get(currentUser);
    
      // Merge prevUser and currentUser data stored in Firebase.
      // Note: How you handle this is specific to your application
      const mergedData = repo.merge(prevUserData, currentUserData);
    
      const credential = OAuthProvider.credentialFromResult(result);
      return linkWithCredential(prevUser, credential)
        .then((linkResult) => {
          // Sign in with the newly linked credential
          const linkCredential = OAuthProvider.credentialFromResult(linkResult);
          return signInWithCredential(auth, linkCredential);
        })
        .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);
    });

    API dengan namespace web

    // 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);
    });

Untuk menambahkan kredensial alamat email dan sandi ke akun pengguna yang ada:

  1. Proses login pengguna menggunakan penyedia atau metode autentikasi apa pun.
  2. Mintalah pengguna mengisi alamat email dan sandi baru.
  3. Buat objek AuthCredential dengan alamat email dan sandi tersebut:

    API modular web

    import { EmailAuthProvider } from "firebase/auth";
    
    const credential = EmailAuthProvider.credential(email, password);

    API dengan namespace web

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Teruskan objek AuthCredential ke metode linkWithCredential pengguna yang login:

    API modular web

    import { getAuth, linkWithCredential } from "firebase/auth";
    
    const auth = getAuth();
    linkWithCredential(auth.currentUser, credential)
      .then((usercred) => {
        const user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

    API dengan namespace web

    auth.currentUser.linkWithCredential(credential)
      .then((usercred) => {
        var user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

    Panggilan ke linkWithCredential akan gagal jika kredensial sudah ditautkan ke akun pengguna lain. Dalam situasi ini, Anda harus menangani penggabungan akun dan data terkait dengan cara yang sesuai untuk aplikasi Anda (lihat contoh di atas).

Anda dapat membatalkan tautan penyedia autentikasi dengan akun, sehingga pengguna tidak dapat login lagi dengan penyedia tersebut.

Untuk membatalkan tautan penyedia autentikasi dengan akun pengguna, teruskan ID penyedia ke metode unlink. Anda dapat memperoleh ID penyedia autentikasi yang tertaut dengan pengguna dari properti providerData.

API modular web

import { getAuth, unlink } from "firebase/auth";

const auth = getAuth();
unlink(auth.currentUser, providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});

API dengan namespace web

user.unlink(providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});