העברת משתמשים מאפליקציה קיימת

במסמך הזה מוסבר איך להעביר משתמשים מאפליקציה קיימת אל Identity Platform.

לפני שמתחילים

שימוש ב-Admin SDK

ה-SDK לאדמינים מאפשר לייבא משתמשים בלי לייצא נתוני משתמש ל-CSV או ל-JSON. אתם יכולים לייבא משתמשים לכל הספקים ש-Identity Platform תומך בהם, כולל OAuth,‏ SAML ו-OIDC.

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

‫SDK לאדמינים מנסה להעלות את כל רשימת המשתמשים שסופקה, גם אם מתרחשת שגיאה שקשורה למשתמש ספציפי. הפעולה מחזירה תוצאה עם סיכום של ייבוא מוצלח וייבוא שנכשל. פרטי השגיאה מוחזרים לכל ייבוא משתמש שנכשל.

ייבוא משתמשים עם סיסמאות מגובבות (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)

המשך

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

ייבוא משתמשים עם סיסמאות שעברו גיבוב באמצעות 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)

המשך

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

ייבוא משתמשים עם סיסמאות שעברו גיבוב SCRYPT רגיל

‫SDK לאדמינים תומך באלגוריתם הרגיל 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)

המשך

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

ייבוא משתמשים עם סיסמאות שעברו גיבוב באמצעות SCRYPT ב-Identity Platform

ב-Identity Platform וב-Firebase נעשה שימוש בגרסה שעברה שינוי של האלגוריתם SCRYPT. אם אתם צריכים להעביר משתמשים מ-Firebase ל-Identity Platform, או מפרויקט אחד ב-Identity Platform לפרויקט אחר, תצטרכו את פרמטרי הגיבוב הפנימיים.

כדי לגשת לפרמטרים ב-Identity Platform:

  1. פותחים את הדף Users במסוף Google Cloud .
  2. לוחצים על ייבוא משתמשים. יופיעו הפרמטרים של הגיבוב של הסיסמה.

כדי לגשת לפרמטרים ב-Firebase:

  1. פותחים את הכרטיסייה Users במסוף Firebase.

  2. בוחרים באפשרות פרמטרים של גיבוב סיסמאות מהתפריט הנפתח בפינה השמאלית העליונה של רשימת המשתמשים. יופיעו הפרמטרים של הגיבוב של הסיסמה.

בקוד צריך לציין את הפרטים הבאים:

  • 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)

המשך

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

ייבוא משתמשים עם סיסמאות מוצפנות ב-BCRYPT

לא נדרשים פרמטרים נוספים או ערכי Salt לסיסמאות מגובבות (hashed) ב-BCRYPT.

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)

המשך

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

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

אם המשתמשים שלכם מבצעים אימות באמצעות ספק זהויות חיצוני באמצעות OAuth,‏ SAML או OIDC, לא תהיה לכם גישה ישירה לסיסמה שלהם.

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)

המשך

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

הערה: providerId משמש ב-Identity Platform לתיאור ספק ספציפי. לספקי OIDC ו-SAML, ההגדרה הזו מוגדרת במהלך היצירה. לספקים אחרים יש ערך מוגדר מראש (לדוגמה, google.com או facebook.com). אפשר לאחזר את providerId מההצהרות של המשתמש המחובר.

ייבוא משתמשים עם מספר גורמי אימות

אם למשתמשים הקיימים שלכם יש מספרי טלפון שרשומים לשימוש באימות רב-שלבי, אתם יכולים לייבא אותם אל Identity Platform.

משתמשים באימות רב-שלבי צריכים לאמת את כתובת האימייל שלהם ולהשתמש בגורם אימות ראשון נתמך. כל משתמש יכול להגדיר עד 5 גורמים משניים.

אפשר לייבא את המאפיינים הבאים של אימות רב-שלבי:

מאפיין (property) סוג תיאור
uid מחרוזת מזהה ייחודי אופציונלי של גורם האימות הנוסף שנרשם. אם לא מציינים ערך, המערכת יוצרת באופן אוטומטי uid אקראי.
phoneNumber מחרוזת מספר הטלפון שרשום כגורם האימות הנוסף. מספר הטלפון הזה צריך להיות תואם לE.164.
displayName מחרוזת שם אופציונלי לתצוגה. האפשרות הזו שימושית אם למשתמש יש כמה שלבי אימות שניים רשומים.
enrollmentTime מחרוזת התאריך שבו נרשם גורם האימות השני, בפורמט של מחרוזת UTC. אם לא תציינו תאריך, המערכת תשתמש בתאריך הנוכחי.
factorId מחרוזת המזהה של סוג הגורם השני. הערך הזה תמיד מוגדר ל-phone.

בדוגמה הבאה אפשר לראות איך מייבאים משתמשים עם אימות רב-שלבי:

Node.js

// Up to 1000 users can be imported at once.
const userImportRecords = [
  {
    uid: 'uid1',
    email: 'user1@example.com',
    emailVerified: true,
    passwordHash: Buffer.from('passwordHash1'),
    passwordSalt: Buffer.from('salt1'),
    multiFactor: {
      enrolledFactors: [
        {
          // Enrolled second factor uid is optional.
          uid: 'uid1-unique-mfa-identifier1',
          displayName: 'Personal phone',
          phoneNumber: '+16505551234',
          factorId: 'phone',
          // Enrollment time is also optional.
          enrollmentTime: 'Fri, 22 Sep 2017 01:49:58 GMT',
        },
      ],
    },
  },
  {
    // User with multiple second factors.
    uid: 'uid2',
    email: 'user2@example.com',
    emailVerified: true,
    passwordHash: Buffer.from('passwordHash2'),
    passwordSalt: Buffer.from('salt2'),
    multiFactor: {
      enrolledFactors: [
        {
          displayName: 'Work phone',
          phoneNumber: '+16505550007',
          factorId: 'phone',
        },
        {
          displayName: 'Backup phone',
          phoneNumber:  '+16505550008',
          factorId: 'phone',
        },
      ],
    },
  },
  {
    // User with no second factor.
    uid: 'uid3',
    email: 'user3@example.com',
    passwordHash: Buffer.from('passwordHash3'),
    passwordSalt: Buffer.from('salt3'),
  },
  ...
];

const userImportOptions = {
  hash: {
    algorithm: 'HMAC_SHA256',
    key: Buffer.from('secretKey'),
  },
};

admin.auth().importUsers(userImportRecords, userImportOptions)
  .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.forEach(function(indexedError) {
      // The corresponding user that failed to upload.
      console.log(userImportRecords[indexedError.index].uid +' failed to import',
          indexedError.error);
    });
  })
  .catch((error) => {
    // Some unrecoverable error occurred that prevented the operation from running.
  });

שימוש בממשק שורת הפקודה (CLI)

אם נתוני המשתמשים שלכם מאוחסנים בפורמט JSON או CSV, אתם יכולים לייבא אותם באמצעות כלי שורת הפקודה של Firebase:

  firebase auth:import account_file       \
    --hash-algo=[HASH-ALGORITHM]          \
    --hash-key=[KEY]                      \
    --salt-separator=[SALT-SEPARATOR]     \
    --rounds=[ROUNDS]                     \
    --mem-cost=[MEM-COST]                 \
    --parallelization=[PARALLELIZATION]   \
    --block-size=[BLOCK-SIZE]             \
    --dk-len=[DK-LEN]                     \
    --hash-input-order=[HASH-INPUT-ORDER] \

תיאור מלא של כל פרמטר מופיע במאמרי העזרה בנושא ממשק שורת הפקודה.

המאמרים הבאים