إنشاء الرموز المميّزة المخصّصة

تمنحك منصة Firebase تحكّمًا كاملاً في المصادقة من خلال السماح لك بمصادقة المستخدمين أو الأجهزة باستخدام رموز JSON المميّزة للويب (JWT) الآمنة. يمكنك إنشاء هذه الرموز المميّزة على الخادم الخاص بك، ثم إرسالها إلى جهاز العميل، ثم استخدامها للمصادقة من خلال طريقة signInWithCustomToken().

لتحقيق ذلك، يجب إنشاء نقطة نهاية للخادم تقبل بيانات اعتماد تسجيل الدخول، مثل اسم المستخدم وكلمة المرور، وإذا كانت بيانات الاعتماد صالحة، يتم عرض رمز JWT مخصّص. يمكن بعد ذلك استخدام رمز JWT المخصّص الذي تم إرجاعه من الخادم بواسطة جهاز عميل للمصادقة مع Firebase (iOS+، Android، الويب). بعد المصادقة، سيتم استخدام هذه الهوية عند الوصول إلى خدمات Firebase الأخرى، مثل Firebase Realtime Database وCloud Storage. بالإضافة إلى ذلك، ستكون محتويات رمز JWT متاحة في عنصر auth في Realtime Database Security Rules وعنصر request.auth في Cloud Storage Security Rules.

يمكنك إنشاء رمز مميّز مخصّص باستخدام مدير SDK في Firebase، أو يمكنك استخدام مكتبة JWT تابعة لجهة خارجية إذا كان الخادم مكتوبًا بلغة لا يتيحها Firebase بشكلٍ تلقائي.

قبل البدء

الرموز المميّزة المخصّصة هي رموز JWT موقَّعة، حيث ينتمي المفتاح الخاص المستخدَم للتوقيع إلى حساب خدمة Google. هناك عدة طرق لتحديد حساب خدمة Google الذي يجب أن يستخدمه مدير SDK في Firebase لتوقيع الرموز المميّزة المخصّصة:

  • السماح لـ "مدير SDK" باكتشاف حساب خدمة -- يمكن استخدام هذه الطريقة في البيئات التي تديرها Google، مثل Google Cloud Functions وApp Engine. قد تحتاج إلى ضبط بعض الأذونات الإضافية من خلال وحدة تحكّم Google Cloud.
  • استخدام رقم تعريف حساب الخدمة: توقّع هذه الطريقة الرموز المميّزة باستخدام المفاتيح المُدارة من Google لحساب الخدمة المحدّد، لذا لن تحتاج إلى التعامل مع أي مفاتيح خاصة بنفسك. يستخدم هذا التطبيق خدمة ويب عن بُعد، وقد تحتاج إلى ضبط أذونات إضافية لحساب الخدمة هذا من خلال وحدة تحكّم Google Cloud.
  • استخدام ملف مفتاح حساب الخدمة: استخدِم هذه الطريقة فقط إذا كان الرمز البرمجي يعمل خارج بيئة تديرها Google ولا يمكنك استخدام أي من الطريقتين أعلاه. ويتطلّب منك إنشاء مفتاح خاص طويل الأمد وتخزينه وحمايته.

ننصحك باستخدام الطريقتَين الأوليَين لأنّهما لا تتطلّبان تنزيل مفاتيح حسابات الخدمة أو إدارتها.

السماح لـ مدير SDK باكتشاف حساب الخدمة

إذا تم نشر الرمز في بيئة تديرها Google، يمكن لـ "مدير SDK" محاولة الاكتشاف التلقائي لطريقة توقيع الرموز المميّزة المخصّصة:

  • إذا تم نشر الرمز البرمجي في بيئة App Engine العادية للغات Java أو Python أو Go، يمكن لمدير SDK استخدام خدمة إدارة الهوية المتوفّرة في تلك البيئة لتوقيع الرموز المميّزة المخصّصة. توقّع خدمة "هوية التطبيق" البيانات باستخدام حساب خدمة تم توفيره لتطبيقك من خلال Google App Engine.

  • إذا تم نشر الرمز البرمجي في بيئة مُدارة أخرى (مثل Google Cloud Functions أو Google Compute Engine)، يمكن لمدير SDK في Firebase اكتشاف سلسلة رقم تعريف حساب الخدمة تلقائيًا من خادم البيانات الوصفية المحلي. يتم بعد ذلك استخدام رقم تعريف حساب الخدمة الذي تم اكتشافه مع خدمة "إدارة الهوية وإمكانية الوصول" (IAM) لتوقيع الرموز المميّزة عن بُعد.

للاستفادة من طرق التوقيع هذه، عليك إعداد حزمة SDK باستخدام بيانات الاعتماد التلقائية للتطبيق من Google وعدم تحديد سلسلة رقم تعريف حساب الخدمة:

Node.js

initializeApp();

Java

FirebaseApp.initializeApp();

Python

default_app = firebase_admin.initialize_app()

متابعة

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

#C

FirebaseApp.Create();

لاختبار الرمز نفسه محليًا بدون تنزيل مفتاح حساب خدمة، سجِّل الدخول باستخدام بيانات اعتماد المستخدم الخاصة بك من خلال Google Cloud CLI:

gcloud auth application-default login

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

إذا كان على مدير SDK في Firebase اكتشاف سلسلة رقم تعريف حساب الخدمة، فإنه يفعل ذلك عندما ينشئ الرمز الخاص بك رمزًا مميزًا مخصصًا لأول مرة. يتم تخزين النتيجة مؤقتًا وإعادة استخدامها لعمليات توقيع الرموز المميّزة اللاحقة. عادةً ما يكون رقم تعريف حساب الخدمة الذي يتم اكتشافه تلقائيًا أحد حسابات الخدمة التلقائية التي يوفّرها Google Cloud:

كما هو الحال مع أرقام تعريف حسابات الخدمة المحدّدة صراحةً، يجب أن يكون لأرقام تعريف حسابات الخدمة التي يتم اكتشافها تلقائيًا إذن iam.serviceAccounts.signBlob لكي تعمل عملية إنشاء الرموز المميّزة المخصّصة. قد تحتاج إلى استخدام قسم إدارة الهوية وإمكانية الوصول والمشرف في وحدة تحكّم Google Cloud لمنح حسابات الخدمة التلقائية الأذونات اللازمة. لمزيد من التفاصيل، يُرجى الاطّلاع على قسم تحديد المشاكل وحلّها أدناه.

استخدام رقم تعريف حساب الخدمة

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

يمكن العثور على رقم تعريف حساب الخدمة في وحدة تحكّم Google Cloud. أرقام تعريف حسابات الخدمة هي عناوين بريد إلكتروني بالتنسيق التالي: <client-id>@<project-id>.iam.gserviceaccount.com. وهي تحدّد بشكل فريد حسابات الخدمة في Firebase ومشاريع "Google Cloud".

لإنشاء رموز مميّزة مخصّصة باستخدام رقم تعريف حساب خدمة منفصل، عليك إعداد حزمة تطوير البرامج (SDK) كما هو موضّح أدناه:

Node.js

initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);

Python

options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)

متابعة

conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

#C

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});

لا تُعدّ أرقام تعريف حسابات الخدمة معلومات حساسة، وبالتالي فإنّ الكشف عنها لا يؤدي إلى أي عواقب. ومع ذلك، لتوقيع الرموز المميّزة المخصّصة باستخدام حساب الخدمة المحدّد، يجب أن يستدعي "مدير SDK في Firebase" خدمة عن بُعد. علاوةً على ذلك، عليك أيضًا التأكّد من أنّ الهوية التي يستخدمها مدير SDK لإجراء هذا الطلب —عادةً {project-name}@appspot.gserviceaccount.com في مرحلة الإنتاج، أو حساب المستخدم الخاص بك أثناء التطوير المحلي— لديها إذن iam.serviceAccounts.signBlob. لمزيد من التفاصيل، يُرجى الاطّلاع على قسم تحديد المشاكل وحلّها أدناه.

استخدام ملف مفتاح حساب الخدمة

إذا كان الرمز البرمجي يعمل في بيئة خارج Google Cloud حيث لا تتوفّر أي من الطريقتين المذكورتين أعلاه، يمكنك إعداد حزمة SDK للمشرف باستخدام ملف مفتاح حساب الخدمة. يُرجى اتّباع تعليمات إعداد Admin SDK للاطّلاع على التفاصيل. باستخدام هذه الطريقة، يوقّع مدير SDK الرموز المميّزة المخصّصة محليًا باستخدام المفتاح الخاص في الملف، بدون إجراء طلبات بيانات من واجهة برمجة التطبيقات عن بُعد.

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

إنشاء رموز مميّزة مخصّصة باستخدام مدير SDK في Firebase

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

Node.js

const uid = 'some-uid';

getAuth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

Python

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

متابعة

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

#C

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

يمكنك أيضًا تحديد مطالبات إضافية ليتم تضمينها في الرمز المميّز المخصّص. على سبيل المثال، في ما يلي، تمت إضافة حقل premiumAccount إلى الرمز المميّز المخصّص، والذي سيكون متاحًا في كائنَي auth / request.auth في &quot;قواعد الأمان&quot;:

Node.js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

getAuth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

Python

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

متابعة

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

#C

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

أسماء الرموز المميّزة المخصّصة المحجوزة

تسجيل الدخول باستخدام رموز مميّزة مخصّصة على برامج العملاء

بعد إنشاء رمز مميّز مخصّص، عليك إرساله إلى تطبيق العميل. تتم مصادقة تطبيق العميل باستخدام الرمز المميّز المخصّص من خلال طلب signInWithCustomToken():

iOS+‎

Objective-C
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
Swift
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
  // ...
}

Android

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

Unity

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.AuthResult result = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      result.User.DisplayName, result.User.UserId);
});

C++‎

firebase::Future<firebase::auth::AuthResult> result =
    auth->SignInWithCustomToken(custom_token);

Web

firebase.auth().signInWithCustomToken(token)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

Web

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

const auth = getAuth();
signInWithCustomToken(auth, token)
  .then((userCredential) => {
    // Signed in
    const user = userCredential.user;
    // ...
  })
  .catch((error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
    // ...
  });

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

بالطريقة نفسها المتّبعة مع طرق تسجيل الدخول الأخرى (مثل signInWithEmailAndPassword() وsignInWithCredential())، ستتم تعبئة العنصر auth في Realtime Database Security Rules والعنصر request.auth في Cloud Storage Security Rules باستخدام uid الخاص بالمستخدم. في هذه الحالة، سيكون uid هو الذي حددته عند إنشاء الرمز المميز المخصص.

قواعد قاعدة البيانات

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

قواعد التخزين

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}

إذا كان الرمز المميّز المخصّص يحتوي على مطالبات إضافية، يمكن الإشارة إليها من خلال العنصر auth.token (Firebase Realtime Database) أو request.auth.token (Cloud Storage) في قواعدك:

قواعد قاعدة البيانات

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

قواعد التخزين

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

إنشاء رموز مميّزة مخصّصة باستخدام مكتبة JWT تابعة لجهة خارجية

إذا كانت الخلفية بلغة لا تحتوي على حزمة تطوير برامج (SDK) رسمية لمشرف Firebase، سيظل بإمكانك إنشاء رموز مميزة مخصصة يدويًا. أولاً، ابحث عن مكتبة JWT تابعة لجهة خارجية للغتك. بعد ذلك، استخدِم مكتبة JWT هذه لإنشاء رمز JWT يتضمّن المطالبات التالية:

مطالبات الرموز المميّزة المخصّصة
alg خوارزمية "RS256"
iss جهة الإصدار عنوان البريد الإلكتروني لحساب الخدمة الخاص بمشروعك
sub الموضوع عنوان البريد الإلكتروني لحساب الخدمة الخاص بمشروعك
aud الجمهور "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat وقت الإصدار الوقت الحالي بالثواني منذ بدء حقبة يونكس
exp وقت انتهاء الصلاحية الوقت بالثواني منذ بداية حقبة يونكس، والذي تنتهي فيه صلاحية الرمز المميّز. ويمكن أن يكون بحد أقصى 3600 ثانية بعد iat.
ملاحظة: يتحكّم هذا الإعداد فقط في وقت انتهاء صلاحية الرمز المميّز المخصّص نفسه. ولكن بعد تسجيل دخول المستخدم باستخدام signInWithCustomToken()، سيظل مسجِّلاً الدخول إلى الجهاز إلى أن يتم إبطال جلسته أو يسجِّل المستخدم الخروج.
uid يجب أن يكون المعرّف الفريد للمستخدم الذي سجّل الدخول عبارة عن سلسلة تتراوح بين حرف واحد و128 حرفًا، بما في ذلك هذين الرقمين. وتوفّر قيم uid الأقصر أداءً أفضل.
‫claims (اختياري) المطالبات المخصّصة الاختيارية التي يجب تضمينها في متغيّرات قواعد الأمان auth / request.auth

في ما يلي بعض الأمثلة على عمليات التنفيذ لكيفية إنشاء رموز مميزة مخصصة في مجموعة متنوعة من اللغات التي لا يدعمها مدير SDK في Firebase. توقّع هذه الأمثلة الرموز المميّزة محليًا باستخدام مفتاح خاص لحساب الخدمة، لذا تنطبق إرشادات الأمان لملفات مفاتيح حساب الخدمة. لتجنُّب إدارة مفتاح خاص، يمكنك بدلاً من ذلك أن تطلب من Google توقيع حمولة الرمز المميّز عن بُعد من خلال استدعاء طريقة signJwt في واجهة برمجة التطبيقات IAM Service Account Credentials API. يحتاج المتصل إلى دور منشئ الرمز المميّز لحساب الخدمة في حساب الخدمة.

PHP

باستخدام php-jwt:

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Placeholder values. In production, load your service account's email
// address and private key from a secure secret store. Never hard-code
// private keys in source code.
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

لغة Ruby

باستخدام ruby-jwt:

require "jwt"

# Placeholder values. In production, load your service account's email
# address and private key from a secure secret store. Never hard-code
# private keys in source code.
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

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

تحديد المشاكل وحلّها

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

واجهة برمجة تطبيقات IAM غير مفعَّلة

إذا كنت تحدّد رقم تعريف حساب خدمة لتوقيع الرموز المميّزة، قد يظهر لك خطأ مشابه لما يلي:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

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

لا يملك حساب الخدمة الأذونات المطلوبة

إذا لم يكن حساب الخدمة الذي يتم تشغيل مدير SDK في Firebase من خلاله يملك الإذن iam.serviceAccounts.signBlob، قد تظهر لك رسالة خطأ مثل الرسالة التالية:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

لحلّ هذه المشكلة، عليك منح دور منشئ الرمز المميّز لحساب الخدمة في "إدارة الهوية وإمكانية الوصول" إلى حساب الخدمة المناسب. يعتمد حساب الخدمة التلقائي المستخدَم على البيئة وإصدار Cloud Functions:

  • ‫Cloud Functions (الجيل الأول): تستخدم حساب خدمة App Engine التلقائي.
  • ‫Cloud Functions (الجيل الثاني): تستخدم حساب خدمة Compute Engine التلقائي.
  1. في وحدة تحكّم Google Cloud، انتقِل إلى إدارة الهوية وإمكانية الوصول والمشرف.

  2. انقر على رمز التعديل المقابل لحساب الخدمة الذي تريد تعديله.

  3. انقر على إضافة دور آخر.

  4. اكتب "Service Account Token Creator" في فلتر البحث، واختَره من النتائج.

  5. انقر على حفظ لتأكيد منح الدور.

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

تعذّر تحديد حساب الخدمة

إذا ظهرت لك رسالة خطأ مشابهة لما يلي، يعني ذلك أنّه لم يتم إعداد حزمة تطوير البرامج (SDK) لمشرف Firebase بشكل صحيح.

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

إذا كنت تعتمد على حزمة تطوير البرامج (SDK) لاكتشاف رقم تعريف حساب الخدمة تلقائيًا، تأكَّد من نشر الرمز في بيئة Google مُدارة باستخدام خادم بيانات وصفية. وإلا، تأكَّد من تحديد رقم تعريف حساب الخدمة عند إعداد حزمة تطوير البرامج (SDK)، أو في البيئات غير التابعة لـ Google، يمكنك إعداد حزمة تطوير البرامج (SDK) باستخدام ملف مفتاح حساب الخدمة.