إضافة تسجيل الدخول بسهولة إلى تطبيق Android باستخدام FirebaseUI

FirebaseUI هي مكتبة تستند إلى حزمة تطوير البرامج (SDK) لميزة "مصادقة Firebase"، وتوفّر مسارات واجهة مستخدم جاهزة للاستخدام في تطبيقك. تقدّم FirebaseUI المزايا التالية:

  • مزوّدون متعدّدون : مسارات تسجيل الدخول باستخدام البريد الإلكتروني/كلمة المرور، ورابط البريد الإلكتروني، والمصادقة عبر الهاتف، وميزة "تسجيل الدخول باستخدام حساب Google"، وميزة "تسجيل الدخول باستخدام حساب Facebook"، وميزة "تسجيل الدخول باستخدام حساب Twitter"، وميزة "تسجيل الدخول باستخدام حساب GitHub"
  • إدارة الحسابات : مسارات للتعامل مع مهام إدارة الحسابات، مثل إنشاء الحسابات وإعادة ضبط كلمات المرور
  • ربط الحساب : مسارات لربط حسابات المستخدمين بأمان بين مزوّدي الهوية
  • ترقية حساب المستخدم المجهول : مسارات لترقية حسابات المستخدمين المجهولين بأمان
  • مظاهر مخصّصة : يمكنك تخصيص مظهر FirebaseUI ليتطابق مع تطبيقك. أيضًا، بما أنّ FirebaseUI مفتوحة المصدر، يمكنك إنشاء نسخة من المشروع وتخصيصها بما يتناسب مع احتياجاتك.
  • Credential Manager : عملية دمج تلقائية مع Credential Manager لتسجيل الدخول بسرعة على أجهزة متعدّدة

قبل البدء

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

  2. أضِف التبعيات الخاصة بـ FirebaseUI إلى ملف build.gradle(.kts) على مستوى التطبيق. إذا أردت إتاحة ميزة "تسجيل الدخول باستخدام حساب Facebook" أو "تسجيل الدخول باستخدام حساب Twitter"، عليك أيضًا تضمين حزمتَي تطوير البرامج (SDK) الخاصتَين بهما:

        dependencies {
            // ...
    
            implementation("com.firebaseui:firebase-ui-auth:9.0.0")
    
            // Required only if Facebook login support is required
            // Find the latest Facebook SDK releases here: https://goo.gl/Ce5L94
            implementation("com.facebook.android:facebook-android-sdk:8.x")
        }
    

    تتضمّن حزمة تطوير البرامج (SDK) لميزة "مصادقة FirebaseUI" تبعيات متعدّية على حزمة تطوير البرامج (SDK) لمنصة Firebase وحزمة تطوير البرامج (SDK) لخدمات Google Play.

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

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

  5. إذا فعّلت ميزة "تسجيل الدخول باستخدام حساب Google":

    1. عدِّل ملف إعداد Firebase.

      1. عندما يُطلب منك ذلك في وحدة تحكّم Firebase، نزِّل ملف إعداد Firebase المعدَّل (google-services.json) الذي يتضمّن الآن معلومات عميل OAuth المطلوبة لتسجيل الدخول باستخدام حساب Google.

      2. انقل ملف الإعداد المعدَّل هذا إلى مشروع استوديو Android، مع استبدال ملف الإعداد المقابل الذي أصبح قديمًا. (راجِع مقالة إضافة Firebase إلى مشروع Android).

    2. حدِّد الملف المرجعي SHA-1 لتطبيقك إذا لم يسبق لك إجراء ذلك.

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

      2. انتقِل للأسفل إلى بطاقة تطبيقاتك ، واختَر تطبيق Android، وأضِف الملف المرجعي SHA-1 في حقل الملفات المرجعية لشهادة SHA.

      راجِع مقالة مصادقة العميل للحصول على تفاصيل حول كيفية الحصول على الملف المرجعي SHA لتطبيقك.

  6. إذا كنت تتيح ميزة "تسجيل الدخول باستخدام حساب Facebook" أو "تسجيل الدخول باستخدام حساب Twitter"، أضِف إلى strings.xml موارد السلسلة التي تحدّد معلومات التعريف المطلوبة من كل مزوّد:

    
    <resources>
      <!-- Facebook application ID and custom URL scheme (app ID prefixed by 'fb'). -->
      <string name="facebook_application_id" translatable="false">YOUR_APP_ID</string>
      <string name="facebook_login_protocol_scheme" translatable="false">fbYOUR_APP_ID</string>
    </resources>

تسجيل الدخول

أنشِئ ActivityResultLauncher يسجِّل معاودة الاتصال لعقد نتيجة النشاط في FirebaseUI:

Kotlin

// See: https://developer.android.com/training/basics/intents/result
private val signInLauncher = registerForActivityResult(
    FirebaseAuthUIActivityResultContract(),
) { res ->
    this.onSignInResult(res)
}

Java

// See: https://developer.android.com/training/basics/intents/result
private final ActivityResultLauncher<Intent> signInLauncher = registerForActivityResult(
        new FirebaseAuthUIActivityResultContract(),
        new ActivityResultCallback<FirebaseAuthUIAuthenticationResult>() {
            @Override
            public void onActivityResult(FirebaseAuthUIAuthenticationResult result) {
                onSignInResult(result);
            }
        }
);

لبدء مسار تسجيل الدخول في FirebaseUI، أنشِئ هدف تسجيل دخول باستخدام طرق تسجيل الدخول المفضّلة لديك:

Kotlin

// Choose authentication providers
val providers = arrayListOf(
    AuthUI.IdpConfig.EmailBuilder().build(),
    AuthUI.IdpConfig.PhoneBuilder().build(),
    AuthUI.IdpConfig.GoogleBuilder().build(),
    AuthUI.IdpConfig.FacebookBuilder().build(),
    AuthUI.IdpConfig.TwitterBuilder().build(),
)

// Create and launch sign-in intent
val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .build()
signInLauncher.launch(signInIntent)

Java

// Choose authentication providers
List<AuthUI.IdpConfig> providers = Arrays.asList(
        new AuthUI.IdpConfig.EmailBuilder().build(),
        new AuthUI.IdpConfig.PhoneBuilder().build(),
        new AuthUI.IdpConfig.GoogleBuilder().build(),
        new AuthUI.IdpConfig.FacebookBuilder().build(),
        new AuthUI.IdpConfig.TwitterBuilder().build());

// Create and launch sign-in intent
Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .build();
signInLauncher.launch(signInIntent);

عند اكتمال مسار تسجيل الدخول، ستتلقّى النتيجة في onSignInResult:

Kotlin

private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
    val response = result.idpResponse
    if (result.resultCode == RESULT_OK) {
        // Successfully signed in
        val user = FirebaseAuth.getInstance().currentUser
        // ...
    } else {
        // Sign in failed. If response is null the user canceled the
        // sign-in flow using the back button. Otherwise check
        // response.getError().getErrorCode() and handle the error.
        // ...
    }
}

Java

private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
    IdpResponse response = result.getIdpResponse();
    if (result.getResultCode() == RESULT_OK) {
        // Successfully signed in
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        // ...
    } else {
        // Sign in failed. If response is null the user canceled the
        // sign-in flow using the back button. Otherwise check
        // response.getError().getErrorCode() and handle the error.
        // ...
    }
}

إعداد طرق تسجيل الدخول

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

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

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

  4. عليك أيضًا تفعيل ميزة Firebase Dynamic Links لاستخدام تسجيل الدخول باستخدام رابط البريد الإلكتروني:

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

    2. انقر على البدء، ثم أضِف نطاقًا. سيظهر النطاق الذي تختاره هنا في روابط البريد الإلكتروني التي يتم إرسالها إلى المستخدمين.

  5. يمكنك تفعيل تسجيل الدخول باستخدام رابط البريد الإلكتروني في FirebaseUI من خلال استدعاء enableEmailLinkSignIn على مثيل EmailBuilder. عليك أيضًا تقديم عنصر ActionCodeSettings صالح مع ضبط setHandleCodeInApp على "صحيح".

    بالإضافة إلى ذلك، عليك إدراج عنوان URL الذي تمرّره إلى setUrl في القائمة البيضاء:

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

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

    Kotlin

    val actionCodeSettings = ActionCodeSettings.newBuilder()
        .setAndroidPackageName( // yourPackageName=
            "...", // installIfNotAvailable=
            true, // minimumVersion=
            null,
        )
        .setHandleCodeInApp(true) // This must be set to true
        .setUrl("https://google.com") // This URL needs to be whitelisted
        .build()
    
    val providers = listOf(
        EmailBuilder()
            .enableEmailLinkSignIn()
            .setActionCodeSettings(actionCodeSettings)
            .build(),
    )
    val signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .build()
    signInLauncher.launch(signInIntent)

    Java

    ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder()
            .setAndroidPackageName(
                    /* yourPackageName= */ "...",
                    /* installIfNotAvailable= */ true,
                    /* minimumVersion= */ null)
            .setHandleCodeInApp(true) // This must be set to true
            .setUrl("https://google.com") // This URL needs to be whitelisted
            .build();
    
    List<AuthUI.IdpConfig> providers = Arrays.asList(
            new AuthUI.IdpConfig.EmailBuilder()
                    .enableEmailLinkSignIn()
                    .setActionCodeSettings(actionCodeSettings)
                    .build()
    );
    Intent signInIntent = AuthUI.getInstance()
            .createSignInIntentBuilder()
            .setAvailableProviders(providers)
            .build();
    signInLauncher.launch(signInIntent);
  6. إذا أردت التقاط الرابط في نشاط معيّن، يُرجى اتّباع الخطوات الموضّحة هنا. وإلا، سيتم إعادة توجيه الرابط إلى نشاط مشغّل التطبيق.

  7. بعد التقاط الرابط المؤدي إلى محتوى معيّن، عليك استدعاء دالة للتحقّق من إمكانية معالجته نيابةً عنك. إذا كان بإمكاننا معالجته، عليك بعد ذلك تمريره إلينا من خلال setEmailLink.

    Kotlin

    if (AuthUI.canHandleIntent(intent)) {
        val extras = intent.extras ?: return
        val link = extras.getString("email_link_sign_in")
        if (link != null) {
            val signInIntent = AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setEmailLink(link)
                .setAvailableProviders(providers)
                .build()
            signInLauncher.launch(signInIntent)
        }
    }

    Java

    if (AuthUI.canHandleIntent(getIntent())) {
        if (getIntent().getExtras() == null) {
            return;
        }
        String link = getIntent().getExtras().getString("email_link_sign_in");
        if (link != null) {
            Intent signInIntent = AuthUI.getInstance()
                    .createSignInIntentBuilder()
                    .setEmailLink(link)
                    .setAvailableProviders(providers)
                    .build();
            signInLauncher.launch(signInIntent);
        }
    }
  8. اختياري : يتمّ تسجيل الدخول باستخدام رابط البريد الإلكتروني على أجهزة متعدّدة، ما يعني أنّه يمكن استخدام الرابط الذي يتم إرساله من خلال تطبيق Android لتسجيل الدخول إلى تطبيقات الويب أو تطبيقات Apple. تكون ميزة تسجيل الدخول على أجهزة متعدّدة مفعّلة تلقائيًا. يمكنك إيقافها من خلال استدعاء setForceSameDevice على مثيل EmailBuilder.

    لمزيد من المعلومات، يُرجى الاطّلاع على FirebaseUI-Web وFirebaseUI-iOS.

تسجيل الخروج

توفّر FirebaseUI طرقًا سهلة لتسجيل الخروج من "مصادقة Firebase" وجميع مزوّدي الهوية على وسائل التواصل الاجتماعي:

Kotlin

AuthUI.getInstance()
    .signOut(this)
    .addOnCompleteListener {
        // ...
    }

Java

AuthUI.getInstance()
        .signOut(this)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            public void onComplete(@NonNull Task<Void> task) {
                // ...
            }
        });

يمكنك أيضًا حذف حساب المستخدم بالكامل:

Kotlin

AuthUI.getInstance()
    .delete(this)
    .addOnCompleteListener {
        // ...
    }

Java

AuthUI.getInstance()
        .delete(this)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // ...
            }
        });

التخصيص

تستخدم FirebaseUI تلقائيًا AppCompat لتطبيق المظاهر، ما يعني أنّها ستعتمد بشكل طبيعي نظام الألوان في تطبيقك. إذا كنت بحاجة إلى تخصيص إضافي، يمكنك تمرير مظهر وشعار إلى أداة إنشاء Intent لتسجيل الدخول:

Kotlin

val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .setLogo(R.drawable.my_great_logo) // Set logo drawable
    .setTheme(R.style.MySuperAppTheme) // Set theme
    .build()
signInLauncher.launch(signInIntent)

Java

Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .setLogo(R.drawable.my_great_logo)      // Set logo drawable
        .setTheme(R.style.MySuperAppTheme)      // Set theme
        .build();
signInLauncher.launch(signInIntent);

يمكنك أيضًا ضبط سياسة خصوصية وبنود خدمة مخصّصة:

Kotlin

val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .setTosAndPrivacyPolicyUrls(
        "https://example.com/terms.html",
        "https://example.com/privacy.html",
    )
    .build()
signInLauncher.launch(signInIntent)

Java

Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .setTosAndPrivacyPolicyUrls(
                "https://example.com/terms.html",
                "https://example.com/privacy.html")
        .build();
signInLauncher.launch(signInIntent);

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

  • لمزيد من المعلومات حول استخدام FirebaseUI وتخصيصها، يُرجى الاطّلاع على ملف README على GitHub.
  • إذا عثرت على مشكلة في FirebaseUI وأردت الإبلاغ عنها، استخدِم أداة تتبُّع المشاكل على GitHub.