匯入使用者

Firebase Admin SDK 提供 Auth.importUsers() API,可透過提升的權限將大量使用者匯入 Firebase AuthenticationFirebase CLI 也提供這項功能,但使用 Admin SDK 時,您可以透過程式輔助方式,從外部驗證系統或其他 Firebase 專案上傳現有使用者,不必建立中繼 CSV 或 JSON 檔案。

使用者匯入 API 具有下列優點:

  • 可使用不同的密碼雜湊演算法,從外部驗證系統遷移使用者。
  • 可遷移其他 Firebase 專案的使用者。
  • 最佳化大量匯入作業,提高速度和效率。這項作業會處理使用者,但不檢查 uidemailphoneNumber 或其他 ID 是否重複。
  • 能夠遷移現有或建立新的 OAuth 使用者 (Google、Facebook 等)。
  • 可直接大量匯入具有自訂聲明的使用者。

用量

單一 API 呼叫最多可匯入 1,000 位使用者。請注意,這項作業已針對速度進行最佳化,不會檢查 uidemailphoneNumber 和其他不重複 ID 是否重複。如果匯入的使用者與現有 uid 發生衝突,系統會取代現有使用者。如果匯入的使用者有任何其他重複的欄位 (例如 email),系統會建立具有相同值的額外使用者。因此,使用這項 API 時,請務必確保沒有重複任何專屬欄位。

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'),   },   //... ]; 

Java

// 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'     ), ] 

Go

// 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 雜湊演算法,重新雜湊處理使用者的密碼。請參閱下文,進一步瞭解各演算法的必填欄位。

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 使用者等),請勿提供雜湊選項。

匯入使用 Firebase scrypt 雜湊密碼的使用者

根據預設,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);   }); 

Java

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) 

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("[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 演算法和修改版 (如上)。如為標準 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);   }); 

Java

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) 

Go

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

Java

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) 

Go

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 雜湊演算法包括:MD5SHA1SHA256SHA512PBKDF_SHA1PBKDF2_SHA256。使用這些雜湊演算法時,您必須提供用於雜湊密碼的回合數 (MD5 為 0 到 8192 之間,SHA1SHA256SHA512 為 1 到 8192 之間,PBKDF_SHA1PBKDF2_SHA256 為 0 到 120000 之間)。

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

Java

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) 

Go

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

Java

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) 

Go

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 雜湊密碼的使用者記錄。請注意,目前只有 Admin Java SDK 支援這項功能。

建構這個演算法的雜湊選項時,需要下列參數:

  • hashLengthBytes:以位元組為單位的所需雜湊長度,以整數形式提供
  • hashType:要使用的 Argon2 變體 (ARGON2_DARGON2_IDARGON2_I)
  • parallelism:平行處理作業程度,以整數形式提供。必須介於 1 到 16 之間 (含 1 和 16)
  • iterations:要執行的疊代次數,以整數形式提供。必須介於 1 到 16 之間 (含 1 和 16)
  • memoryCostKib:此演算法所需的記憶體成本 (以千位元組為單位),必須小於 32768。
  • version:Argon2 演算法版本 (VERSION_10VERSION_13)。這是選用參數,如未指定,預設為 VERSION_13。
  • associatedData:以位元組陣列形式提供的額外關聯資料,會附加至雜湊值,提供額外一層安全防護。(選用) 這項資料會先經過 Base64 編碼,再傳送至 API。

Java

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

Java

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) 

Go

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