ייבוא משתמשים

‫Firebase Admin SDK מספק את ה-API‏ Auth.importUsers() לייבוא משתמשים בכמות גדולה אל Firebase Authentication עם הרשאות גבוהות. התכונה הזו זמינה גם ב-Firebase CLI, אבל Admin SDK מאפשר לכם להעלות משתמשים קיימים ממערכת אימות חיצונית או מפרויקט אחר ב-Firebase באופן פרוגרמטי, בלי שתצטרכו ליצור קובצי CSV או JSON ביניים.

ל-User Import API יש את היתרונות הבאים:

  • אפשרות להעביר משתמשים ממערכת אימות חיצונית באמצעות אלגוריתם שונה לגיבוב סיסמאות.
  • אפשרות להעביר משתמשים מפרויקט אחר ב-Firebase.
  • אופטימיזציה לפעולות ייבוא בכמות גדולה, מהירות ויעילות. בפעולה הזו המערכת מעבדת את המשתמשים בלי לבדוק אם יש כפילויות של uid, email, phoneNumber או מזהים אחרים.
  • אפשרות להעביר משתמשי OAuth קיימים או ליצור משתמשי OAuth חדשים (Google,‏ Facebook וכו').
  • אפשרות לייבא משתמשים עם טענות מותאמות אישית ישירות בכמות גדולה.

שימוש

אפשר לייבא עד 1,000 משתמשים בקריאת API אחת. שימו לב שהפעולה הזו מותאמת למהירות ולא בודקת כפילויות של uid, email, phoneNumber ומזהים ייחודיים אחרים. אם מייבאים משתמש שמתנגש עם uid קיים, המשתמש הקיים יוחלף. אם מייבאים משתמש עם שדה אחר שמופיע פעמיים (למשל email), יתווסף משתמש עם אותו ערך. לכן, כשמשתמשים בממשק ה-API הזה, צריך לוודא שלא משכפלים שדות ייחודיים.

Node.js

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

Java

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

Python

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

Go

// Up to 1000 users can be imported at once.
var users []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
	UID("uid1").
	Email("user1@example.com").
	PasswordHash([]byte("passwordHash1")).
	PasswordSalt([]byte("salt1")))
users = append(users, (&auth.UserToImport{}).
	UID("uid2").
	Email("user2@example.com").
	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 = "user1@example.com",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash1"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt1"),
    },
    new ImportUserRecordArgs()
    {
        Uid = "uid2",
        Email = "user2@example.com",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash2"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt2"),
    },
};

בדוגמה הזו, אפשרויות הגיבוב מצוינות כדי לעזור ל-Firebase לאמת את המשתמשים האלה בצורה מאובטחת בפעם הבאה שהם ינסו להיכנס באמצעות Firebase Authentication. אחרי שהמשתמש מתחבר בהצלחה, Firebase מבצע גיבוב מחדש של הסיסמה שלו באמצעות אלגוריתם הגיבוב הפנימי של Firebase. בהמשך מופיע מידע נוסף על השדות הנדרשים לכל אלגוריתם.

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

Java

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(
        f'Successfully imported {result.success_count} users. Failed to import '
        f'{result.failure_count} users.')
    for err in result.errors:
        print(f'Failed to import {users[err.index].uid} due to {err.reason}')
except exceptions.FirebaseError:
    # Some unrecoverable error occurred that prevented the operation from running.
    pass

Go

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 משתמשת בגרסה של אלגוריתם הגיבוב scrypt שמותאמת ל-Firebase כדי לאחסן סיסמאות. ייבוא של סיסמאות שעברו גיבוב באמצעות scrypt שעבר שינוי שימושי להעברת משתמשים מפרויקט Firebase קיים אחר. כדי לעשות את זה, צריך לקבוע את הפרמטרים הפנימיים של הפרויקט המקורי.

מערכת Firebase יוצרת פרמטרים ייחודיים של גיבוב סיסמאות לכל פרויקט ב-Firebase. כדי לגשת לפרמטרים האלה, עוברים לכרטיסייה Users במסוף Firebase ובוחרים באפשרות Password Hash Parameters מהתפריט הנפתח בפינה השמאלית העליונה של טבלת רשימת המשתמשים.

הפרמטרים שנדרשים כדי ליצור את אפשרויות הגיבוב לאלגוריתם הזה כוללים:

  • key: מפתח החתימה שמועבר בדרך כלל בקידוד base64.
  • saltSeparator: מפריד המלח שמופיע בדרך כלל בקידוד base64(אופציונלי).
  • rounds: מספר הסבבים שמשמשים לגיבוב הסיסמאות.
  • memoryCost: עלות הזיכרון שנדרשת לאלגוריתם הזה.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: 'user@example.com',
        // 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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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='user@example.com',
        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)

Go

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("user@example.com").
		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 = "user@example.com",
            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 הרגיל וגם בגרסה ששונתה (למעלה). כדי להשתמש באלגוריתם scrypt רגיל, צריך לציין את פרמטרים הגיבוב הבאים:

  • memoryCost: העלות של אלגוריתם הגיבוב במונחים של CPU/זיכרון.
  • parallelization: טעינה במקביל של אלגוריתם הגיבוב.
  • blockSize: גודל הבלוק (בדרך כלל 8) של אלגוריתם הגיבוב.
  • derivedKeyLength: אורך המפתח הנגזר של אלגוריתם הגיבוב

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: 'user@example.com',
        // 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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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='user@example.com',
        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)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		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 = "user@example.com",
            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}");
}

ייבוא משתמשים עם סיסמאות מגובבות (hashed) מסוג HMAC

אלגוריתמים לגיבוב HMAC כוללים: HMAC_MD5, HMAC_SHA1, HMAC_SHA256 ו-HMAC_SHA512. עבור אלגוריתמי הגיבוב האלה, צריך לספק את מפתח החתימה של הגיבוב.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: 'user@example.com',
        // 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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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='user@example.com',
        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)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		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 = "user@example.com",
            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 ל-8,192 עבור MD5, בין 1 ל-8,192 עבור SHA1, SHA256 ו-SHA512, ובין 0 ל-120,000 עבור PBKDF_SHA1 ו-PBKDF2_SHA256) ששימשו לגיבוב הסיסמה.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: 'user@example.com',
        // 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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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='user@example.com',
        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)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		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 = "user@example.com",
            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, לא נדרשים פרמטרים נוספים של גיבוב או ערכי Salt של סיסמאות לכל משתמש.

Node.js

getAuth()
  .importUsers(
    [
      {
        uid: 'some-uid',
        email: 'user@example.com',
        // 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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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='user@example.com',
        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)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		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 = "user@example.com",
            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 אובייקט גיבוב. הערה: נכון לעכשיו, האפשרות הזו נתמכת רק ב-Admin 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 לפני שהם נשלחים ל-API.

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setEmail("user@example.com")
      .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: 'johndoe@gmail.com',
      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: 'johndoe@gmail.com',
          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);
  });

Java

try {
  List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
      .setUid("some-uid")
      .setDisplayName("John Doe")
      .setEmail("johndoe@gmail.com")
      .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("johndoe@gmail.com")
          .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='johndoe@gmail.com',
        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='johndoe@gmail.com',
                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)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		DisplayName("John Doe").
		Email("johndoe@gmail.com").
		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:       "johndoe@gmail.com",
				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 = "johndoe@gmail.com",
            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 = "johndoe@gmail.com",
                    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}");
}