المصادقة في Firebase باستخدام رابط البريد الإلكتروني في Android

يمكنك استخدام Firebase Authentication لتسجيل دخول مستخدم من خلال إرسال رسالة إلكترونية إليه تحتوي على رابط يمكنه النقر عليه لتسجيل الدخول. وفي هذه العملية، يتم أيضًا إثبات عنوان البريد الإلكتروني للمستخدم.

هناك العديد من المزايا لتسجيل الدخول عن طريق البريد الإلكتروني:

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

قبل البدء

إعداد مشروع Android

  1. أضِف Firebase إلى مشروع Android الخاص بك، في حال لم يسبق لك إجراء ذلك، .

  2. في ملف Gradle للوحدة (على مستوى التطبيق) (عادةً ما يكون <project>/<app-module>/build.gradle.kts أو <project>/<app-module>/build.gradle)، أضِف الاعتمادية لمكتبة Firebase Authentication لنظام التشغيل Android. ننصحك باستخدام الـ Firebase Android BoM للتحكّم في إصدار المكتبة.

    كجزء من إعداد Firebase Authentication، عليك أيضًا إضافة حزمة تطوير البرامج (SDK) لخدمات Google Play إلى تطبيقك.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:34.19.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:22.0.0")
    }

    باستخدام Firebase Android BoM، سيستخدم تطبيقك دائمًا إصدارات متوافقة من مكتبات Firebase لنظام التشغيل Android.

    (حلّ بديل)  إضافة اعتماديات مكتبة Firebase بدون استخدام BoM

    إذا اخترت عدم استخدام Firebase BoM، عليك تحديد إصدار كل مكتبة من مكتبات Firebase في سطر الاعتمادية الخاص بها.

    يُرجى العِلم أنّه إذا كنت تستخدم مكتبات متعددة من Firebase في تطبيقك، ننصحك بشدة باستخدام BoM لإدارة إصدارات المكتبات، ما يضمن توافق جميع الإصدارات.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:24.2.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:22.0.0")
    }

تفعيل تسجيل الدخول باستخدام رابط البريد الإلكتروني لمشروع Firebase

لتسجيل دخول المستخدمين باستخدام رابط البريد الإلكتروني، عليك أولاً تفعيل موفِّر البريد الإلكتروني وطريقة تسجيل الدخول باستخدام رابط البريد الإلكتروني لمشروعك على Firebase:

  1. في وحدة تحكّم Firebase، انتقِل إلى الأمان > المصادقة.

  2. في علامة التبويب طريقة تسجيل الدخول ، فعِّل موفِّر تسجيل الدخول البريد الإلكتروني/كلمة المرور. يُرجى العِلم أنّه يجب تفعيل تسجيل الدخول باستخدام البريد الإلكتروني/كلمة المرور لاستخدام تسجيل الدخول باستخدام رابط البريد الإلكتروني.

  3. في القسم نفسه، فعِّل موفِّر تسجيل الدخول رابط البريد الإلكتروني (تسجيل الدخول بدون كلمة مرور).

  4. انقر على حفظ.

لبدء عملية المصادقة، اعرض على المستخدم واجهة تطلب منه تقديم عنوان بريده الإلكتروني، ثم استدعِ الدالة sendSignInLinkToEmail لطلب إرسال رابط المصادقة إلى عنوان البريد الإلكتروني للمستخدم من Firebase.

  1. أنشئ عنصر ActionCodeSettings الذي يزوّد Firebase بتعليمات حول كيفية إنشاء رابط البريد الإلكتروني. اضبط الحقول التالية:

    • url: الرابط لصفحة معيّنة في التطبيق الذي سيتم تضمينه وأي حالة إضافية سيتم تمريرها. أضِف نطاق الرابط إلى قائمة النطاقات المفوّضة إذا لم يسبق لك إجراء ذلك:

      1. في وحدة تحكّم Firebase، انتقِل إلى علامة التبويب الأمان > المصادقة > الإعدادات.

      2. في قسم النطاقات المفوّضة ، انقر على إضافة نطاق، وأضِف نطاق الرابط.

      سيتم إعادة توجيه المستخدم إلى عنوان URL هذا إذا لم يكن التطبيق مثبّتًا على جهازه ولم يكن من الممكن تثبيته.

    • androidPackageName وiOSBundleId: يساعدان Firebase Authentication في تحديد ما إذا كان يجب إنشاء رابط للويب فقط أو رابط للأجهزة الجوّالة يتم فتحه على جهاز Android أو Apple.
    • handleCodeInApp: اضبط القيمة على "صحيح". يجب دائمًا إكمال عملية تسجيل الدخول في التطبيق على عكس الإجراءات الأخرى خارج نطاق البريد الإلكتروني (إعادة ضبط كلمة المرور وعمليات إثبات عنوان البريد الإلكتروني). في نهاية العملية، من المفترض أن يكون المستخدم مسجّلاً الدخول وأن تظل حالة المصادقة محفوظة في التطبيق.
    • linkDomain: عند تحديد نطاقات روابط مخصّصة Hosting لخدمة Firebase Hosting لمشروع، حدِّد النطاق الذي سيتم استخدامه عند فتح الرابط من خلال تطبيق محدّد على الأجهزة الجوّالة. بخلاف ذلك، يتم اختيار النطاق التلقائي تلقائيًا (على سبيل المثال، PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: تم إيقاف هذه المَعلمة نهائيًا. لا تحدِّد هذه المَعلمة.

    Kotlin

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
            "com.example.android",
            true, // installIfNotAvailable
            "12", // minimumVersion
        )
    }

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    لمزيد من المعلومات عن ActionCodeSettings، يُرجى الرجوع إلى الـ تمرير الحالة في إجراءات البريد الإلكتروني قسم.

  2. اطلب من المستخدم عنوان بريده الإلكتروني.

  3. أرسِل رابط المصادقة إلى عنوان البريد الإلكتروني للمستخدم، واحفظ عنوان البريد الإلكتروني للمستخدم في حال أكمل المستخدم عملية تسجيل الدخول باستخدام البريد الإلكتروني على الجهاز نفسه.

    Kotlin

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Email sent.")
            }
        }

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

المخاوف المرتبطة بالأمان

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

يمكنك تبسيط هذه العملية للمستخدمين الذين يفتحون رابط تسجيل الدخول على الجهاز نفسه الذي يطلبون الرابط عليه، وذلك من خلال تخزين عنوان بريدهم الإلكتروني محليًا، على سبيل المثال باستخدام SharedPreferences، عند إرسال رسالة تسجيل الدخول الإلكترونية. بعد ذلك، استخدِم هذا العنوان لإكمال العملية. لا تمرِّر عنوان البريد الإلكتروني للمستخدم في مَعلمات عنوان URL لإعادة التوجيه وأعِد استخدامه، لأنّ ذلك قد يتيح عمليات إدخال الجلسات.

بعد إكمال تسجيل الدخول، ستتم إزالة أي آلية تسجيل دخول سابقة لم يتم إثباتها من المستخدم وسيتم إبطال أي جلسات حالية. على سبيل المثال، إذا سبق لأحد المستخدمين إنشاء حساب لم يتم إثباته باستخدام عنوان البريد الإلكتروني وكلمة المرور نفسَيهما، ستتم إزالة كلمة مرور المستخدم لمنع المنتحل الذي ادّعى ملكية هذا الحساب غير المُثبَت وأنشأه من تسجيل الدخول مرة أخرى باستخدام عنوان البريد الإلكتروني وكلمة المرور غير المُثبَتَين.

تأكَّد أيضًا من استخدام عنوان URL لبروتوكول HTTPS في بيئة الإنتاج لتجنُّب اعتراض الرابط المحتمل من قِبل خوادم وسيطة.

إكمال تسجيل الدخول في تطبيق Android

Firebase Authentication يستخدم Firebase Hosting لإرسال رابط البريد الإلكتروني إلى جهاز جوّال. لإكمال تسجيل الدخول من خلال تطبيق الأجهزة الجوّالة، يجب ضبط التطبيق على رصد رابط التطبيق الوارد وتحليل الرابط لصفحة معيّنة في التطبيق الأساسي ثم إكمال تسجيل الدخول. لمزيد من المعلومات، يُرجى الاطّلاع على مستندات روابط تطبيقات Android.

ضبط Firebase Hosting

Firebase Authentication يستخدم نطاقات Firebase Hosting عند إنشاء وإرسال رابط من المفترض فتحه في تطبيق الأجهزة الجوّالة. تمّ ضبط نطاق تلقائي لخدمة Firebase Hosting لك من قبل.

  1. اضبط Firebase Hosting نطاقات:

    في وحدة تحكّم Firebase، انتقِل إلى الاستضافة والخدمات بلا خادم > الاستضافة.

    • إذا كنت تريد استخدام النطاق التلقائي لرابط البريد الإلكتروني الذي يتم فتحه في تطبيقات الأجهزة الجوّالة، انتقِل إلى موقعك الإلكتروني التلقائي واحتفِظ بنطاق الاستضافة التلقائي Hosting. عادةً ما يبدو نطاق Hosting التلقائي على النحو التالي: هذا: PROJECT_ID.firebaseapp.com.

      ستحتاج إلى هذه القيمة عند ضبط تطبيقك لاعتراض الرابط الوارد.

    • إذا كنت تريد استخدام نطاق مخصّص لرابط البريد الإلكتروني، يمكنك تسجيل نطاق باستخدام Firebase Hosting واستخدامه لنطاق الرابط.

  2. ضبط تطبيقات Android:

    للتعامل مع هذه الروابط من تطبيق Android، يجب تحديد اسم حزمة تطبيقك في وحدة تحكّمFirebaseإعدادات مشروع. بالإضافة إلى ذلك، يجب تقديم SHA-1 وSHA-256 لشهادة التطبيق.

    إذا كنت تريد أن تتم إعادة توجيه هذه الروابط إلى نشاط معيّن، عليك ضبط intent filter في ملف AndroidManifest.xml. يجب أن يرصد فلتر الأهداف روابط البريد الإلكتروني لنطاقك. في AndroidManifest.xml:

    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data
        android:scheme="https"
        android:host="<PROJECT_ID>.firebaseapp.com or your custom domain"
        android:pathPrefix="/__/auth/links" />
    </intent-filter>
    

    عندما يفتح المستخدمون رابط استضافة باستخدام المسار /__/auth/links والمخطط والمضيف اللذين تحدّدهما، سيبدأ تطبيقك النشاط باستخدام فلتر الأهداف هذا للتعامل مع الرابط.

بعد تلقّي الرابط كما هو موضّح أعلاه، تحقَّق من أنّه مخصّص لمصادقة رابط البريد الإلكتروني وأكمِل عملية تسجيل الدخول.

Kotlin

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully signed in with email link!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error signing in with email link", task.exception)
            }
        }
}

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

لمزيد من المعلومات عن كيفية التعامل مع تسجيل الدخول باستخدام رابط البريد الإلكتروني في تطبيق Apple، يُرجى الرجوع إلى دليل منصات Apple.

للتعرّف على كيفية التعامل مع تسجيل الدخول باستخدام رابط البريد الإلكتروني في تطبيق ويب، يُرجى الرجوع إلى دليل الويب.

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

سيختلف النصف الثاني من العملية:

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d(TAG, "Successfully linked emailLink credential!")
            val result = task.result
            // You can access the new user via result.getUser()
            // Additional user info profile *not* available via:
            // result.getAdditionalUserInfo().getProfile() == null
            // You can check if the user is new or existing:
            // result.getAdditionalUserInfo().isNewUser()
        } else {
            Log.e(TAG, "Error linking emailLink credential", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

يمكن أيضًا استخدام هذه الطريقة لإعادة مصادقة مستخدم رابط البريد الإلكتروني قبل تشغيل عملية حساسة.

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is now successfully reauthenticated
        } else {
            Log.e(TAG, "Error reauthenticating", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

ومع ذلك، بما أنّ العملية قد تنتهي على جهاز مختلف لم يكن المستخدم الأصلي مسجّلاً الدخول إليه، قد لا يتم إكمال هذه العملية. في هذه الحالة، يمكن عرض رسالة خطأ للمستخدم لإجباره على فتح الرابط على الجهاز نفسه. يمكن تمرير بعض الحالات في الرابط لتقديم معلومات عن نوع العملية ورقم تعريف المستخدم.

كانت مصادقة رابط البريد الإلكتروني تعتمد سابقًا على Firebase Dynamic Links، التي سيتم إيقافها في 25 أغسطس 2025.

لقد نشرنا حلاً بديلاً في Firebase Authentication Android SDK v23.2.0 والإصدارات الأحدث وFirebase BoM v33.9.0 والإصدارات الأحدث.

إذا كان تطبيقك يستخدم الروابط القديمة، عليك نقل تطبيقك إلى النظام الجديد Firebase Hosting المستند إلى النظام.

إذا أنشأت مشروعك في 15 سبتمبر 2023 أو بعد هذا التاريخ، يتم تفعيل ميزة الحماية من تعداد عناوين البريد الإلكتروني تلقائيًا. تحسّن هذه الميزة أمان حسابات المستخدمين في مشروعك، ولكنّها توقف طريقة fetchSignInMethodsForEmail()، التي سبق أن نصحنا بتنفيذ عمليات تسجيل الدخول باستخدام المعرّف أولاً.

على الرغم من أنّه يمكنك إيقاف ميزة الحماية من تعداد عناوين البريد الإلكتروني لمشروعك، ننصحك بعدم إجراء ذلك.

لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات الحماية من تعداد عناوين البريد الإلكتروني .

الخطوات التالية

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

  • في تطبيقاتك، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من الـ FirebaseUser كائن. يُرجى الاطّلاع على إدارة المستخدمين.

  • في Firebase Realtime Database وCloud Storage قواعد الأمان، يمكنك الحصول على رقم تعريف المستخدم الفريد للمستخدم الذي سجّل الدخول من متغيّر auth، واستخدامه للتحكّم في البيانات التي يمكن للمستخدم الوصول إليها.

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

لتسجيل خروج مستخدم، استدعِ الدالة signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();