ربط عدة مقدّمي خدمات مصادقة بحساب باستخدام JavaScript

يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام عدة موفِّري مصادقة من خلال ربط بيانات اعتماد موفِّر المصادقة بحساب مستخدم حالي. ويمكن التعرّف على المستخدمين من خلال رقم تعريف مستخدم Firebase نفسه بغض النظر عن موفِّر المصادقة الذي تم استخدامه لتسجيل الدخول. على سبيل المثال، يمكن للمستخدم الذي سجّل الدخول باستخدام كلمة مرور ربط حساب Google وتسجيل الدخول بأي من الطريقتين في المستقبل. أو يمكن للمستخدم المجهول ربط حساب Facebook ثم تسجيل الدخول لاحقًا باستخدام Facebook لمتابعة استخدام التطبيق.

قبل البدء

أضِف إلى تطبيقك دعمًا لاثنين أو أكثر من مزوّدي خدمات المصادقة (ربما يشمل ذلك المصادقة المجهولة).

لربط بيانات الاعتماد من موفِّر مصادقة، مثل Google أو Facebook، بحساب مستخدم حالي:

  1. سجِّل دخول المستخدم باستخدام أي موفِّر مصادقة أو طريقة مصادقة.
  2. احصل على عنصر AuthProvider المقابل لموفّر الخدمة الذي تريد ربطه بحساب المستخدم. أمثلة:

    واجهة برمجة التطبيقات Web modular API

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

    واجهة برمجة التطبيقات لمساحة الاسم على الويب

    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. اطلب من المستخدم تسجيل الدخول من خلال مقدّم الخدمة الذي تريد ربطه. يمكنك أن تطلب من المستخدمين تسجيل الدخول إما من خلال فتح نافذة منبثقة أو إعادة التوجيه إلى صفحة تسجيل الدخول الخاصة بمقدّم الخدمة. وننصح باستخدام طريقة إعادة التوجيه على الأجهزة الجوّالة.
    • لتسجيل الدخول عبر نافذة منبثقة، اتصل بالرقم linkWithPopup:

      واجهة برمجة التطبيقات Web modular API

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

      واجهة برمجة التطبيقات لمساحة الاسم على الويب

      auth.currentUser.linkWithPopup(provider).then((result) => {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    • لتسجيل الدخول من خلال إعادة التوجيه إلى صفحة تسجيل الدخول الخاصة بمقدّم الخدمة، اطلب linkWithRedirect: اتّبِع أفضل الممارسات عند استخدام "linkWithRedirect".

      واجهة برمجة التطبيقات Web modular API

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

      واجهة برمجة التطبيقات لمساحة الاسم على الويب

      auth.currentUser.linkWithRedirect(provider)
        .then(/* ... */)
        .catch(/* ... */);
      بعد أن يسجِّل المستخدم دخوله، ستتم إعادة توجيهه إلى صفحتك. بعد ذلك، يمكنك استرداد نتيجة تسجيل الدخول من خلال طلب getRedirectResult عند تحميل الصفحة:

      واجهة برمجة التطبيقات Web modular API

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

      واجهة برمجة التطبيقات لمساحة الاسم على الويب

      auth.getRedirectResult().then((result) => {
        if (result.credential) {
          // Accounts successfully linked.
          var credential = result.credential;
          var user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    إذا سجّل المستخدم الدخول بنجاح، يتم ربط حساب المستخدم لدى مقدّم الخدمة بحساب المستخدم في مشروع Firebase.

    ولن تنجح عملية ربط الحساب إذا كانت بيانات الاعتماد مرتبطة بحساب مستخدم آخر. وفي هذه الحالة، يجب التعامل مع عملية دمج الحسابات والبيانات المرتبطة بها على النحو المناسب لتطبيقك:

    واجهة برمجة التطبيقات Web modular API

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

    واجهة برمجة التطبيقات لمساحة الاسم على الويب

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

لإضافة بيانات اعتماد عنوان البريد الإلكتروني وكلمة المرور إلى حساب مستخدم حالي:

  1. سجِّل دخول المستخدم باستخدام أي موفِّر مصادقة أو طريقة مصادقة.
  2. اطلب من المستخدم إدخال عنوان بريد إلكتروني وكلمة مرور جديدة.
  3. أنشِئ عنصر AuthCredential باستخدام عنوان البريد الإلكتروني وكلمة المرور:

    واجهة برمجة التطبيقات Web modular API

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

    واجهة برمجة التطبيقات لمساحة الاسم على الويب

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. مرِّر الكائن AuthCredential إلى طريقة linkWithCredential الخاصة بالمستخدم الذي سجّل الدخول:

    واجهة برمجة التطبيقات Web modular API

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

    واجهة برمجة التطبيقات لمساحة الاسم على الويب

    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 إذا كانت بيانات الاعتماد مرتبطة بحساب مستخدم آخر. وفي هذه الحالة، يجب التعامل مع عملية دمج الحسابات والبيانات المرتبطة بها على النحو المناسب لتطبيقك (راجِع المثال أعلاه).

يمكنك إلغاء ربط موفِّر مصادقة بحساب، حتى لا يتمكّن المستخدم من تسجيل الدخول من خلال ذلك الحساب مرة أخرى.

لإلغاء ربط موفِّر مصادقة بحساب مستخدم، أرسِل رقم تعريف مقدِّم الخدمة إلى الطريقة unlink. يمكنك الحصول على أرقام تعريف موفّري المصادقة تم ربطهم بمستخدم من الموقع providerData.

واجهة برمجة التطبيقات Web modular API

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

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

واجهة برمجة التطبيقات لمساحة الاسم على الويب

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