استيراد المستخدمين

توفّر حزمة Firebase Admin SDK واجهة برمجة التطبيقات Auth.importUsers() لاستيراد المستخدمين بشكلٍ مجمّع إلى Firebase Authentication باستخدام امتيازات مميّزة. على الرغم من توفّر هذه الميزة أيضًا في واجهة برمجة تطبيقات Firebase CLI، تسمح لك حزمة Admin SDK بتحميل المستخدمين الحاليين من نظام مصادقة خارجي أو مشروع Firebase آخر آليًا بدون الحاجة إلى إنشاء ملفات CSV أو JSON وسيطة.

توفّر واجهة برمجة التطبيقات لاستيراد المستخدمين المزايا التالية:

  • إمكانية نقل المستخدمين من نظام مصادقة خارجي باستخدام خوارزمية تجزئة مختلفة لكلمات المرور
  • إمكانية نقل بيانات المستخدمين من مشروع آخر على Firebase
  • تحسين عمليات الاستيراد المجمّعة السريعة والفعّالة تعالج هذه العملية المستخدمين بدون التحقّق من تكرار uid أو email أو phoneNumber أو أي معرّف آخر.
  • إمكانية نقل بيانات مستخدمي OAuth الحاليين أو إنشاء مستخدمين جدد (Google وFacebook وغيرها).
  • إمكانية استيراد المستخدمين الذين لديهم مطالبات مخصّصة مباشرةً بشكل مجمّع

الاستخدام

يمكن استيراد ما يصل إلى 1,000 مستخدم في طلب بيانات واحد من واجهة برمجة التطبيقات. يُرجى العِلم أنّ هذه العملية محسّنة لزيادة السرعة ولا تتحقّق من تكرار uid وemail وphoneNumber وغيرها من المعرّفات الفريدة. سيؤدي استيراد مستخدم يتضارب مع uid حالي إلى استبدال المستخدم الحالي. سيؤدي استيراد مستخدم يتضمّن أي حقل آخر مكرّر (مثل email) إلى إضافة مستخدم إضافي بالقيمة نفسها. وبالتالي، عند استخدام واجهة برمجة التطبيقات هذه، يجب التأكّد من عدم تكرار أي حقول فريدة.

Node.js

// Up to 1000 users can be imported at once.
const userImportRecords = [
  {
    uid: 'uid1',
    email: '[email protected]',
    passwordHash: Buffer.from('passwordHash1'),
    passwordSalt: Buffer.from('salt1'),
  },
  {
    uid: 'uid2',
    email: '[email protected]',
    passwordHash: Buffer.from('passwordHash2'),
    passwordSalt: Buffer.from('salt2'),
  },
  //...
];

جافا

// Up to 1000 users can be imported at once.
List<ImportUserRecord> users = new ArrayList<>();
users.add(ImportUserRecord.builder()
    .setUid("uid1")
    .setEmail("[email protected]")
    .setPasswordHash("passwordHash1".getBytes())
    .setPasswordSalt("salt1".getBytes())
    .build());
users.add(ImportUserRecord.builder()
    .setUid("uid2")
    .setEmail("[email protected]")
    .setPasswordHash("passwordHash2".getBytes())
    .setPasswordSalt("salt2".getBytes())
    .build());

Python

# Up to 1000 users can be imported at once.
users = [
    auth.ImportUserRecord(
        uid='uid1',
        email='[email protected]',
        password_hash=b'password_hash_1',
        password_salt=b'salt1'
    ),
    auth.ImportUserRecord(
        uid='uid2',
        email='[email protected]',
        password_hash=b'password_hash_2',
        password_salt=b'salt2'
    ),
]

انتقال

// Up to 1000 users can be imported at once.
var users []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
	UID("uid1").
	Email("[email protected]").
	PasswordHash([]byte("passwordHash1")).
	PasswordSalt([]byte("salt1")))
users = append(users, (&auth.UserToImport{}).
	UID("uid2").
	Email("[email protected]").
	PasswordHash([]byte("passwordHash2")).
	PasswordSalt([]byte("salt2")))

#C

//  Up to 1000 users can be imported at once.
var users = new List<ImportUserRecordArgs>()
{
    new ImportUserRecordArgs()
    {
        Uid = "uid1",
        Email = "[email protected]",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash1"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt1"),
    },
    new ImportUserRecordArgs()
    {
        Uid = "uid2",
        Email = "[email protected]",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash2"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt2"),
    },
};

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

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

Node.js

getAuth()
  .importUsers(userImportRecords, {
    hash: {
      algorithm: 'HMAC_SHA256',
      key: Buffer.from('secretKey'),
    },
  })
  .then((userImportResult) => {
    // The number of successful imports is determined via: userImportResult.successCount.
    // The number of failed imports is determined via: userImportResult.failureCount.
    // To get the error details.
    userImportResult.errors.forEach((indexedError) => {
      // The corresponding user that failed to upload.
      console.log(
        'Error ' + indexedError.index,
        ' failed to import: ',
        indexedError.error
      );
    });
  })
  .catch((error) => {
    // Some unrecoverable error occurred that prevented the operation from running.
  });

جافا

UserImportOptions options = UserImportOptions.withHash(
    HmacSha256.builder()
        .setKey("secretKey".getBytes())
        .build());
try {
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  System.out.println("Successfully imported " + result.getSuccessCount() + " users");
  System.out.println("Failed to import " + result.getFailureCount() + " users");
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user at index: " + indexedError.getIndex()
        + " due to error: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  // Some unrecoverable error occurred that prevented the operation from running.
}

Python

hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret_key')
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    print('Successfully imported {0} users. Failed to import {1} users.'.format(
        result.success_count, result.failure_count))
    for err in result.errors:
        print('Failed to import {0} due to {1}'.format(users[err.index].uid, err.reason))
except exceptions.FirebaseError:
    # Some unrecoverable error occurred that prevented the operation from running.
    pass

انتقال

client, err := app.Auth(ctx)
if err != nil {
	log.Fatalln("Error initializing Auth client", err)
}

h := hash.HMACSHA256{
	Key: []byte("secretKey"),
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Unrecoverable error prevented the operation from running", err)
}

log.Printf("Successfully imported %d users\n", result.SuccessCount)
log.Printf("Failed to import %d users\n", result.FailureCount)
for _, e := range result.Errors {
	log.Printf("Failed to import user at index: %d due to error: %s\n", e.Index, e.Reason)
}

#C

var options = new UserImportOptions()
{
    Hash = new HmacSha256()
    {
        Key = Encoding.ASCII.GetBytes("secretKey"),
    },
};

try
{
    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    Console.WriteLine($"Successfully imported {result.SuccessCount} users");
    Console.WriteLine($"Failed to import {result.FailureCount} users");
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user at index: {indexedError.Index}"
            + $" due to error: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException)
{
    // Some unrecoverable error occurred that prevented the operation from running.
}

إذا لم تكن هناك حاجة إلى تجزئة كلمة المرور (رقم الهاتف أو مستخدم الرمز المميّز المخصّص أو مستخدم OAuth وما إلى ذلك)، لا تقدِّم خيارات التجزئة.

استيراد المستخدمين باستخدام كلمات المرور المشفَّرة بتقنية scrypt من Firebase

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

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

تشمل المَعلمات المطلوبة لإنشاء خيارات التجزئة لهذه الخوارزمية ما يلي:

  • key: مفتاح الموقّع الذي يتم تقديمه عادةً بترميز base64
  • saltSeparator: فاصل الملح الذي يتم توفيره عادةً بترميز base64 (اختياري)
  • rounds: عدد الجولات المستخدَمة لتجزئة كلمات المرور
  • memoryCost: تكلفة الذاكرة المطلوبة لهذه الخوارزمية

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: '[email protected]',
        // Must be provided in a byte buffer.
        passwordHash: Buffer.from('base64-password-hash', 'base64'),
        // Must be provided in a byte buffer.
        passwordSalt: Buffer.from('base64-salt', 'base64'),
      },
    ],
    {
      hash: {
        algorithm: 'SCRYPT',
        // All the parameters below can be obtained from the Firebase Console's users section.
        // Must be provided in a byte buffer.
        key: Buffer.from('base64-secret', 'base64'),
        saltSeparator: Buffer.from('base64SaltSeparator', 'base64'),
        rounds: 8,
        memoryCost: 14,
      },
    }
  )
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash(BaseEncoding.base64().decode("password-hash"))
      .setPasswordSalt(BaseEncoding.base64().decode("salt"))
      .build());
  UserImportOptions options = UserImportOptions.withHash(
      Scrypt.builder()
          // All the parameters below can be obtained from the Firebase Console's "Users"
          // section. Base64 encoded parameters must be decoded into raw bytes.
          .setKey(BaseEncoding.base64().decode("base64-secret"))
          .setSaltSeparator(BaseEncoding.base64().decode("base64-salt-separator"))
          .setRounds(8)
          .setMemoryCost(14)
          .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        email='[email protected]',
        password_hash=base64.urlsafe_b64decode('password_hash'),
        password_salt=base64.urlsafe_b64decode('salt')
    ),
]

# All the parameters below can be obtained from the Firebase Console's "Users"
# section. Base64 encoded parameters must be decoded into raw bytes.
hash_alg = auth.UserImportHash.scrypt(
    key=base64.b64decode('base64_secret'),
    salt_separator=base64.b64decode('base64_salt_separator'),
    rounds=8,
    memory_cost=14
)
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

b64URLdecode := func(s string) []byte {
	b, err := base64.URLEncoding.DecodeString(s)
	if err != nil {
		log.Fatalln("Failed to decode string", err)
	}

	return b
}
b64Stddecode := func(s string) []byte {
	b, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		log.Fatalln("Failed to decode string", err)
	}
	return b
}
// Users retrieved from Firebase Auth's backend need to be base64URL decoded
users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("[email protected]").
		PasswordHash(b64URLdecode("password-hash")).
		PasswordSalt(b64URLdecode("salt")),
}

// All the parameters below can be obtained from the Firebase Console's "Users"
// section. Base64 encoded parameters must be decoded into raw bytes.
h := hash.Scrypt{
	Key:           b64Stddecode("base64-secret"),
	SaltSeparator: b64Stddecode("base64-salt-separator"),
	Rounds:        8,
	MemoryCost:    14,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "[email protected]",
            PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
            PasswordSalt = Encoding.ASCII.GetBytes("salt"),
        },
    };

    var options = new UserImportOptions()
    {
        // All the parameters below can be obtained from the Firebase Console's "Users"
        // section. Base64 encoded parameters must be decoded into raw bytes.
        Hash = new Scrypt()
        {
            Key = Encoding.ASCII.GetBytes("base64-secret"),
            SaltSeparator = Encoding.ASCII.GetBytes("base64-salt-separator"),
            Rounds = 8,
            MemoryCost = 14,
        },
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}

استيراد المستخدمين باستخدام كلمات مرور عادية تم تجزئتها باستخدام خوارزمية Scrypt

يتوافق Firebase Authentication مع خوارزمية التشفير العادية بالإضافة إلى الإصدار المعدَّل (أعلاه). بالنسبة إلى خوارزمية scrypt العادية، تكون مَعلمات التجزئة التالية مطلوبة:

  • memoryCost: تكلفة وحدة المعالجة المركزية (CPU)/الذاكرة لخوارزمية التجزئة
  • parallelization: معالجة خوارزمية التجزئة بشكل موازٍ
  • blockSize: حجم الكتلة (عادةً 8) لخوارزمية التجزئة
  • derivedKeyLength: طول المفتاح المستمد من خوارزمية التجزئة

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: '[email protected]',
        // Must be provided in a byte buffer.
        passwordHash: Buffer.from('password-hash'),
        // Must be provided in a byte buffer.
        passwordSalt: Buffer.from('salt'),
      },
    ],
    {
      hash: {
        algorithm: 'STANDARD_SCRYPT',
        memoryCost: 1024,
        parallelization: 16,
        blockSize: 8,
        derivedKeyLength: 64,
      },
    }
  )
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash("password-hash".getBytes())
      .setPasswordSalt("salt".getBytes())
      .build());
  UserImportOptions options = UserImportOptions.withHash(
      StandardScrypt.builder()
          .setMemoryCost(1024)
          .setParallelization(16)
          .setBlockSize(8)
          .setDerivedKeyLength(64)
          .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        email='[email protected]',
        password_hash=b'password_hash',
        password_salt=b'salt'
    ),
]

hash_alg = auth.UserImportHash.standard_scrypt(
    memory_cost=1024, parallelization=16, block_size=8, derived_key_length=64)
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("[email protected]").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.StandardScrypt{
	MemoryCost:       1024,
	Parallelization:  16,
	BlockSize:        8,
	DerivedKeyLength: 64,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "[email protected]",
            PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
            PasswordSalt = Encoding.ASCII.GetBytes("salt"),
        },
    };

    var options = new UserImportOptions()
    {
        Hash = new StandardScrypt()
        {
            MemoryCost = 1024,
            Parallelization = 16,
            BlockSize = 8,
            DerivedKeyLength = 64,
        },
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}

استيراد المستخدمين باستخدام كلمات المرور المجزّأة بأسلوب HMAC

تشمل خوارزميات تجزئة HMAC ما يلي: HMAC_MD5 وHMAC_SHA1 وHMAC_SHA256 و HMAC_SHA512. بالنسبة إلى خوارزميات التجزئة هذه، يجب توفير مفتاح توقيع التجزئة.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: '[email protected]',
        // Must be provided in a byte buffer.
        passwordHash: Buffer.from('password-hash'),
        // Must be provided in a byte buffer.
        passwordSalt: Buffer.from('salt'),
      },
    ],
    {
      hash: {
        algorithm: 'HMAC_SHA256',
        // Must be provided in a byte buffer.
        key: Buffer.from('secret'),
      },
    }
  )
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash("password-hash".getBytes())
      .setPasswordSalt("salt".getBytes())
      .build());
  UserImportOptions options = UserImportOptions.withHash(
      HmacSha256.builder()
          .setKey("secret".getBytes())
          .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        email='[email protected]',
        password_hash=b'password_hash',
        password_salt=b'salt'
    ),
]

hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret')
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("[email protected]").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.HMACSHA256{
	Key: []byte("secret"),
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "[email protected]",
            PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
            PasswordSalt = Encoding.ASCII.GetBytes("salt"),
        },
    };

    var options = new UserImportOptions()
    {
        Hash = new HmacSha256()
        {
            Key = Encoding.ASCII.GetBytes("secret"),
        },
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}

استيراد المستخدمين باستخدام كلمات المرور التي تمت تجزئتها باستخدام MD5 وSHA وPBKDF

تشتمل خوارزميات التجزئة MD5 وSHA وPBKDF على: MD5 وSHA1 وSHA256 وSHA512 وPBKDF_SHA1 وPBKDF2_SHA256. بالنسبة إلى خوارزميات التجزئة هذه، يجب تقديم عدد الجولات (بين 0 و8192 لخوارزمية MD5، وبين 1 و8192 لخوارزميّات SHA1 وSHA256 وSHA512، وبين 0 و120000 لخوارزميّات PBKDF_SHA1 وPBKDF2_SHA256) المستخدَمة لتجزئة كلمة المرور.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: '[email protected]',
        // Must be provided in a byte buffer.
        passwordHash: Buffer.from('password-hash'),
        // Must be provided in a byte buffer.
        passwordSalt: Buffer.from('salt'),
      },
    ],
    {
      hash: {
        algorithm: 'PBKDF2_SHA256',
        rounds: 100000,
      },
    }
  )
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash("password-hash".getBytes())
      .setPasswordSalt("salt".getBytes())
      .build());
  UserImportOptions options = UserImportOptions.withHash(
      Pbkdf2Sha256.builder()
          .setRounds(100000)
          .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        email='[email protected]',
        password_hash=b'password_hash',
        password_salt=b'salt'
    ),
]

hash_alg = auth.UserImportHash.pbkdf2_sha256(rounds=100000)
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("[email protected]").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.PBKDF2SHA256{
	Rounds: 100000,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "[email protected]",
            PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
            PasswordSalt = Encoding.ASCII.GetBytes("salt"),
        },
    };

    var options = new UserImportOptions()
    {
        Hash = new Pbkdf2Sha256()
        {
            Rounds = 100000,
        },
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}

استيراد المستخدمين باستخدام كلمات مرور مجزّأة بترميز BCRYPT

بالنسبة إلى كلمات مرور BCRYPT المجزّأة، ليس مطلوبًا استخدام معلَمات تجزئة إضافية أو قيم عشوائية لكلمات المرور لكل مستخدم.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: '[email protected]',
        // Must be provided in a byte buffer.
        passwordHash: Buffer.from('password-hash'),
      },
    ],
    {
      hash: {
        algorithm: 'BCRYPT',
      },
    }
  )
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash("password-hash".getBytes())
      .setPasswordSalt("salt".getBytes())
      .build());
  UserImportOptions options = UserImportOptions.withHash(Bcrypt.getInstance());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        email='[email protected]',
        password_hash=b'password_hash',
        password_salt=b'salt'
    ),
]

hash_alg = auth.UserImportHash.bcrypt()
try:
    result = auth.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("[email protected]").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.Bcrypt{}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "[email protected]",
            PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
            PasswordSalt = Encoding.ASCII.GetBytes("salt"),
        },
    };

    var options = new UserImportOptions()
    {
        Hash = new Bcrypt(),
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}

استيراد المستخدمين باستخدام كلمات مرور مجزّأة بتشفير Argon2

يمكنك استيراد سجلات المستخدمين التي تحتوي على كلمات مرور مجزّأة بأسلوب Argon2 من خلال إنشاء عنصر تجزئة Argon2. يُرجى العلم أنّ هذه الميزة لا تتوفّر حاليًا إلا في حزمة Java SDK للمشرف.

تشمل المَعلمات المطلوبة لإنشاء خيارات التجزئة لهذه الخوارزمية ما يلي:

  • hashLengthBytes: طول التجزئة المطلوب بالبايت، المقدَّم كعدد صحيح
  • hashType: صيغة Argon2 المطلوب استخدامها (ARGON2_D، وARGON2_ID، وARGON2_I)
  • parallelism: درجة التوازي، المقدَّمة كعدد صحيح يجب أن تتراوح القيمة بين 1 و16 (بما في ذلك هذان الرقمان).
  • iterations: عدد التكرارات التي يجب إجراؤها، ويتم تقديمها كعدد صحيح. يجب أن تتراوح القيمة بين 1 و16 (بما في ذلك هذان الرقمان).
  • memoryCostKib: يجب أن تكون تكلفة الذاكرة المطلوبة لهذه الخوارزمية أقل من 32768 كيلوبايت.
  • version: إصدار خوارزمية Argon2 (VERSION_10 أو VERSION_13). اختياري، ويتم ضبطه تلقائيًا على VERSION_13 في حال عدم تحديده.
  • associatedData: بيانات مرتبطة إضافية، يتم تقديمها على شكل صفيف بايت، ويتم إلحاقها بقيمة التجزئة لتوفير طبقة أمان إضافية. اختياري، يتم ترميز هذه البيانات باستخدام Base64 قبل إرسالها إلى واجهة برمجة التطبيقات.

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("[email protected]")
      .setPasswordHash("password-hash".getBytes())
      .setPasswordSalt("salt".getBytes())
      .build());
  UserImportOptions options = UserImportOptions.withHash(
      Argon2.builder()
          .setHashLengthBytes(512)
          .setHashType(Argon2HashType.ARGON2_ID)
          .setParallelism(8)
          .setIterations(16)
          .setMemoryCostKib(2048)
          .setVersion(Argon2Version.VERSION_10)
          .setAssociatedData("associated-data".getBytes())
          .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

استيراد المستخدمين بدون كلمات مرور

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

Node.js

getAuth()
  .importUsers([
    {
      uid: 'some-uid',
      displayName: 'John Doe',
      email: '[email protected]',
      photoURL: 'http://www.example.com/12345678/photo.png',
      emailVerified: true,
      phoneNumber: '+11234567890',
      // Set this user as admin.
      customClaims: { admin: true },
      // User with Google provider.
      providerData: [
        {
          uid: 'google-uid',
          email: '[email protected]',
          displayName: 'John Doe',
          photoURL: 'http://www.example.com/12345678/photo.png',
          providerId: 'google.com',
        },
      ],
    },
  ])
  .then((results) => {
    results.errors.forEach((indexedError) => {
      console.log(`Error importing user ${indexedError.index}`);
    });
  })
  .catch((error) => {
    console.log('Error importing users :', error);
  });

جافا

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setDisplayName("John Doe")
      .setEmail("[email protected]")
      .setPhotoUrl("http://www.example.com/12345678/photo.png")
      .setEmailVerified(true)
      .setPhoneNumber("+11234567890")
      .putCustomClaim("admin", true) // set this user as admin
      .addUserProvider(UserProvider.builder() // user with Google provider
          .setUid("google-uid")
          .setEmail("[email protected]")
          .setDisplayName("John Doe")
          .setPhotoUrl("http://www.example.com/12345678/photo.png")
          .setProviderId("google.com")
          .build())
      .build());
  UserImportResult result = FirebaseAuth.getInstance().importUsers(users);
  for (ErrorInfo indexedError : result.getErrors()) {
    System.out.println("Failed to import user: " + indexedError.getReason());
  }
} catch (FirebaseAuthException e) {
  System.out.println("Error importing users: " + e.getMessage());
}

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        display_name='John Doe',
        email='[email protected]',
        photo_url='http://www.example.com/12345678/photo.png',
        email_verified=True,
        phone_number='+11234567890',
        custom_claims={'admin': True}, # set this user as admin
        provider_data=[ # user with Google provider
            auth.UserProvider(
                uid='google-uid',
                email='[email protected]',
                display_name='John Doe',
                photo_url='http://www.example.com/12345678/photo.png',
                provider_id='google.com'
            )
        ],
    ),
]
try:
    result = auth.import_users(users)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

انتقال

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		DisplayName("John Doe").
		Email("[email protected]").
		PhotoURL("http://www.example.com/12345678/photo.png").
		EmailVerified(true).
		PhoneNumber("+11234567890").
		CustomClaims(map[string]interface{}{"admin": true}). // set this user as admin
		ProviderData([]*auth.UserProvider{                   // user with Google provider
			{
				UID:         "google-uid",
				Email:       "[email protected]",
				DisplayName: "John Doe",
				PhotoURL:    "http://www.example.com/12345678/photo.png",
				ProviderID:  "google.com",
			},
		}),
}
result, err := client.ImportUsers(ctx, users)
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

#C

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            DisplayName = "John Doe",
            Email = "[email protected]",
            PhotoUrl = "http://www.example.com/12345678/photo.png",
            EmailVerified = true,
            PhoneNumber = "+11234567890",
            CustomClaims = new Dictionary<string, object>()
            {
                { "admin", true }, // set this user as admin
            },
            UserProviders = new List<UserProvider>
            {
                new UserProvider() // user with Google provider
                {
                    Uid = "google-uid",
                    Email = "[email protected]",
                    DisplayName = "John Doe",
                    PhotoUrl = "http://www.example.com/12345678/photo.png",
                    ProviderId = "google.com",
                },
            },
        },
    };

    UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users);
    foreach (ErrorInfo indexedError in result.Errors)
    {
        Console.WriteLine($"Failed to import user: {indexedError.Reason}");
    }
}
catch (FirebaseAuthException e)
{
    Console.WriteLine($"Error importing users: {e.Message}");
}