透過程式管理使用者
本文說明如何使用 Identity Platform Admin SDK,以程式輔助方式管理使用者。您可以使用 Admin SDK 執行各種常見的管理工作,例如建立、查詢及修改使用者。
事前準備
取得使用者
依 ID 取得使用者
識別使用者的主要方式是透過uid:
Node.js
getAuth() .getUser(uid) .then((userRecord) => { // See the UserRecord reference doc for the contents of userRecord. console.log(`Successfully fetched user data: ${userRecord.toJSON()}`); }) .catch((error) => { console.log('Error fetching user data:', error); });
Java
UserRecord userRecord = FirebaseAuth.getInstance().getUser(uid); // See the UserRecord reference doc for the contents of userRecord. System.out.println("Successfully fetched user data: " + userRecord.getUid());
Python
from firebase_admin import auth user = auth.get_user(uid) print(f'Successfully fetched user data: {user.uid}')
Go
// Get an auth client from the firebase.App client, err := app.Auth(ctx) if err != nil { log.Fatalf("error getting Auth client: %v\n", err) } u, err := client.GetUser(ctx, uid) if err != nil { log.Fatalf("error getting user %s: %v\n", uid, err) } log.Printf("Successfully fetched user data: %v\n", u)
C#
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(uid); // See the UserRecord reference doc for the contents of userRecord. Console.WriteLine($"Successfully fetched user data: {userRecord.Uid}");
依電子郵件地址取得使用者
您也可以使用電子郵件地址取得使用者:
Node.js
getAuth() .getUserByEmail(email) .then((userRecord) => { // See the UserRecord reference doc for the contents of userRecord. console.log(`Successfully fetched user data: ${userRecord.toJSON()}`); }) .catch((error) => { console.log('Error fetching user data:', error); });
Java
UserRecord userRecord = FirebaseAuth.getInstance().getUserByEmail(email); // See the UserRecord reference doc for the contents of userRecord. System.out.println("Successfully fetched user data: " + userRecord.getEmail());
Python
from firebase_admin import auth user = auth.get_user_by_email(email) print(f'Successfully fetched user data: {user.uid}')
Go
u, err := client.GetUserByEmail(ctx, email) if err != nil { log.Fatalf("error getting user by email %s: %v\n", email, err) } log.Printf("Successfully fetched user data: %v\n", u)
C#
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserByEmailAsync(email); // See the UserRecord reference doc for the contents of userRecord. Console.WriteLine($"Successfully fetched user data: {userRecord.Uid}");
請注意,你只能使用主要電子郵件地址搜尋,無法使用特定供應商的電子郵件地址。舉例來說,如果電子郵件地址為 facebookUser@example.com 的 Facebook 帳戶已連結至電子郵件地址為 user@example.com 的現有使用者,則呼叫 getUserByEmail("facebookUser@example.com") 不會產生任何結果。呼叫 getUserByEmail("user@example.com") 會傳回預期使用者。
主要電子郵件地址取決於帳戶連結設定:
- 連結使用相同電子郵件地址的帳戶:主要電子郵件地址是您用來登入的第一個電子郵件地址,除非您手動更新。
- 為每個身分識別資訊提供者建立多個帳戶:除非手動更新,否則只有在建立密碼使用者時,才會設定主要電子郵件地址。
透過電話號碼取得使用者
如果使用者有電話號碼,您可以透過電話號碼搜尋:
Node.js
getAuth() .getUserByPhoneNumber(phoneNumber) .then((userRecord) => { // See the UserRecord reference doc for the contents of userRecord. console.log(`Successfully fetched user data: ${userRecord.toJSON()}`); }) .catch((error) => { console.log('Error fetching user data:', error); });
Java
UserRecord userRecord = FirebaseAuth.getInstance().getUserByPhoneNumber(phoneNumber); // See the UserRecord reference doc for the contents of userRecord. System.out.println("Successfully fetched user data: " + userRecord.getPhoneNumber());
Python
from firebase_admin import auth user = auth.get_user_by_phone_number(phone) print(f'Successfully fetched user data: {user.uid}')
Go
u, err := client.GetUserByPhoneNumber(ctx, phone) if err != nil { log.Fatalf("error getting user by phone %s: %v\n", phone, err) } log.Printf("Successfully fetched user data: %v\n", u)
C#
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserByPhoneNumberAsync(phoneNumber); // See the UserRecord reference doc for the contents of userRecord. Console.WriteLine($"Successfully fetched user data: {userRecord.Uid}");
大量擷取使用者資料
您也可以根據您提供的 ID 擷取使用者清單。您可以透過使用者 ID、電子郵件地址或電話號碼識別使用者。單次呼叫最多可提供 100 個 ID。ID 可包含多種型別:
Node.js
getAuth() .getUsers([ { uid: 'uid1' }, { email: 'user2@example.com' }, { phoneNumber: '+15555550003' }, { providerId: 'google.com', providerUid: 'google_uid4' }, ]) .then((getUsersResult) => { console.log('Successfully fetched user data:'); getUsersResult.users.forEach((userRecord) => { console.log(userRecord); }); console.log('Unable to find users corresponding to these identifiers:'); getUsersResult.notFound.forEach((userIdentifier) => { console.log(userIdentifier); }); }) .catch((error) => { console.log('Error fetching user data:', error); });
Java
GetUsersResult result = FirebaseAuth.getInstance().getUsersAsync(Arrays.asList( new UidIdentifier("uid1"), new EmailIdentifier("user2@example.com"), new PhoneIdentifier("+15555550003"), new ProviderIdentifier("google.com", "google_uid4"))).get(); System.out.println("Successfully fetched user data:"); for (UserRecord user : result.getUsers()) { System.out.println(user.getUid()); } System.out.println("Unable to find users corresponding to these identifiers:"); for (UserIdentifier uid : result.getNotFound()) { System.out.println(uid); }
Python
from firebase_admin import auth result = auth.get_users([ auth.UidIdentifier('uid1'), auth.EmailIdentifier('user2@example.com'), auth.PhoneIdentifier(+15555550003), auth.ProviderIdentifier('google.com', 'google_uid4') ]) print('Successfully fetched user data:') for user in result.users: print(user.uid) print('Unable to find users corresponding to these identifiers:') for uid in result.not_found: print(uid)
Go
getUsersResult, err := client.GetUsers(ctx, []auth.UserIdentifier{ auth.UIDIdentifier{UID: "uid1"}, auth.EmailIdentifier{Email: "user@example.com"}, auth.PhoneIdentifier{PhoneNumber: "+15555551234"}, auth.ProviderIdentifier{ProviderID: "google.com", ProviderUID: "google_uid1"}, }) if err != nil { log.Fatalf("error retriving multiple users: %v\n", err) } log.Printf("Successfully fetched user data:") for _, u := range getUsersResult.Users { log.Printf("%v", u) } log.Printf("Unable to find users corresponding to these identifiers:") for _, id := range getUsersResult.NotFound { log.Printf("%v", id) }
C#
GetUsersResult result = await FirebaseAuth.DefaultInstance.GetUsersAsync( new List<UserIdentifier> { new UidIdentifier("uid1"), new EmailIdentifier("user2@example.com"), new PhoneIdentifier("+15555550003"), new ProviderIdentifier("google.com", "google_uid4"), }); Console.WriteLine("Successfully fetched user data:"); foreach (UserRecord user in result.Users) { Console.WriteLine($"User: {user.Uid}"); } Console.WriteLine("Unable to find users corresponding to these identifiers:"); foreach (UserIdentifier uid in result.NotFound) { Console.WriteLine($"{uid}"); }
這個方法會傳回與輸入清單大小相同的清單,每個項目都包含對應的 UserRecord 或錯誤,指出無法查閱該 ID 的原因。
列出使用者
以下程式碼顯示如何列出所有使用者:
Node.js
const listAllUsers = (nextPageToken) => { // List batch of users, 1000 at a time. getAuth() .listUsers(1000, nextPageToken) .then((listUsersResult) => { listUsersResult.users.forEach((userRecord) => { console.log('user', userRecord.toJSON()); }); if (listUsersResult.pageToken) { // List next batch of users. listAllUsers(listUsersResult.pageToken); } }) .catch((error) => { console.log('Error listing users:', error); }); }; // Start listing users from the beginning, 1000 at a time. listAllUsers();
Java
// Start listing users from the beginning, 1000 at a time. ListUsersPage page = FirebaseAuth.getInstance().listUsers(null); while (page != null) { for (ExportedUserRecord user : page.getValues()) { System.out.println("User: " + user.getUid()); } page = page.getNextPage(); } // Iterate through all users. This will still retrieve users in batches, // buffering no more than 1000 users in memory at a time. page = FirebaseAuth.getInstance().listUsers(null); for (ExportedUserRecord user : page.iterateAll()) { System.out.println("User: " + user.getUid()); }
Python
# Start listing users from the beginning, 1000 at a time. page = auth.list_users() while page: for user in page.users: print('User: ' + user.uid) # Get next batch of users. page = page.get_next_page() # Iterate through all users. This will still retrieve users in batches, # buffering no more than 1000 users in memory at a time. for user in auth.list_users().iterate_all(): print('User: ' + user.uid)
Go
// Note, behind the scenes, the Users() iterator will retrive 1000 Users at a time through the API iter := client.Users(ctx, "") for { user, err := iter.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("error listing users: %s\n", err) } log.Printf("read user user: %v\n", user) } // Iterating by pages 100 users at a time. // Note that using both the Next() function on an iterator and the NextPage() // on a Pager wrapping that same iterator will result in an error. pager := iterator.NewPager(client.Users(ctx, ""), 100, "") for { var users []*auth.ExportedUserRecord nextPageToken, err := pager.NextPage(&users) if err != nil { log.Fatalf("paging error %v\n", err) } for _, u := range users { log.Printf("read user user: %v\n", u) } if nextPageToken == "" { break } }
C#
// Start listing users from the beginning, 1000 at a time. var pagedEnumerable = FirebaseAuth.DefaultInstance.ListUsersAsync(null); var responses = pagedEnumerable.AsRawResponses().GetAsyncEnumerator(); while (await responses.MoveNextAsync()) { ExportedUserRecords response = responses.Current; foreach (ExportedUserRecord user in response.Users) { Console.WriteLine($"User: {user.Uid}"); } } // Iterate through all users. This will still retrieve users in batches, // buffering no more than 1000 users in memory at a time. var enumerator = FirebaseAuth.DefaultInstance.ListUsersAsync(null).GetAsyncEnumerator(); while (await enumerator.MoveNextAsync()) { ExportedUserRecord user = enumerator.Current; Console.WriteLine($"User: {user.Uid}"); }
系統會分批傳回使用者,並依 uid 排序。每批結果都包含使用者清單,以及用於擷取下一批結果的下一頁權杖。列出所有使用者後,系統不會傳回 pageToken。
maxResult 欄位會指定批量上限。預設值和最大值為 1000。
列出使用者密碼雜湊
由於密碼雜湊屬於機密資訊,因此除非使用者具備 firebaseauth.configs.getHashConfig 權限,否則 Admin SDK 不會傳回這類資訊。預先定義角色不會授予這項權限。如要授予權限,請按照下列步驟操作:
建立自訂角色,授予
firebaseauth.configs.getHashConfig權限。
具備這個自訂角色的使用者後續呼叫 listUsers() 時,系統會一併傳送 passwordHash 和 passwordSalt 欄位。
建立使用者
以程式輔助方式建立新使用者,可避免對一般使用者施加部分限制。您不會受到節流或頻率限制,而且可以略過電子郵件地址和電話號碼的正常驗證程序。
如要建立新使用者,請按照下列步驟操作:
Node.js
getAuth() .createUser({ email: 'user@example.com', emailVerified: false, phoneNumber: '+11234567890', password: 'secretPassword', displayName: 'John Doe', photoURL: 'http://www.example.com/12345678/photo.png', disabled: false, }) .then((userRecord) => { // See the UserRecord reference doc for the contents of userRecord. console.log('Successfully created new user:', userRecord.uid); }) .catch((error) => { console.log('Error creating new user:', error); });
Java
CreateRequest request = new CreateRequest() .setEmail("user@example.com") .setEmailVerified(false) .setPassword("secretPassword") .setPhoneNumber("+11234567890") .setDisplayName("John Doe") .setPhotoUrl("http://www.example.com/12345678/photo.png") .setDisabled(false); UserRecord userRecord = FirebaseAuth.getInstance().createUser(request); System.out.println("Successfully created new user: " + userRecord.getUid());
Python
user = auth.create_user( email='user@example.com', email_verified=False, phone_number='+15555550100', password='secretPassword', display_name='John Doe', photo_url='http://www.example.com/12345678/photo.png', disabled=False) print(f'Sucessfully created new user: {user.uid}')
Go
params := (&auth.UserToCreate{}). Email("user@example.com"). EmailVerified(false). PhoneNumber("+15555550100"). Password("secretPassword"). DisplayName("John Doe"). PhotoURL("http://www.example.com/12345678/photo.png"). Disabled(false) u, err := client.CreateUser(ctx, params) if err != nil { log.Fatalf("error creating user: %v\n", err) } log.Printf("Successfully created user: %v\n", u)
C#
UserRecordArgs args = new UserRecordArgs() { Email = "user@example.com", EmailVerified = false, PhoneNumber = "+11234567890", Password = "secretPassword", DisplayName = "John Doe", PhotoUrl = "http://www.example.com/12345678/photo.png", Disabled = false, }; UserRecord userRecord = await FirebaseAuth.DefaultInstance.CreateUserAsync(args); // See the UserRecord reference doc for the contents of userRecord. Console.WriteLine($"Successfully created new user: {userRecord.Uid}");
您可以為新使用者設定下列任一屬性。所有屬性皆為選用。
| 屬性 | 類型 | 說明 |
|---|---|---|
uid |
字串 |
指派給新建立使用者的 uid。必須是長度介於 1 至 128 個字元之間的字串 (含首尾)。如未提供,系統會自動產生隨機 uid。 |
email |
字串 | 使用者的主要電子郵件地址。請輸入有效的電子郵件地址。 |
emailVerified |
布林值 |
使用者的主要電子郵件地址是否已通過驗證。如未提供,則預設為 false。
|
phoneNumber |
字串 | 使用者的主要電話號碼。必須是符合 E.164 規格的有效電話號碼。 |
password |
字串 | 使用者的原始密碼 (未經過雜湊處理)。長度不得少於六個字元。 |
displayName |
字串 | 使用者的顯示名稱。 |
photoURL |
字串 | 使用者的相片網址。 |
disabled |
布林值 |
使用者是否已停用。true (已停用);
false (已啟用)。如未提供,預設值為 false。
|
更新使用者
Node.js
getAuth() .updateUser(uid, { email: 'modifiedUser@example.com', phoneNumber: '+11234567890', emailVerified: true, password: 'newPassword', displayName: 'Jane Doe', photoURL: 'http://www.example.com/12345678/photo.png', disabled: true, }) .then((userRecord) => { // See the UserRecord reference doc for the contents of userRecord. console.log('Successfully updated user', userRecord.toJSON()); }) .catch((error) => { console.log('Error updating user:', error); });
Java
UpdateRequest request = new UpdateRequest(uid) .setEmail("user@example.com") .setPhoneNumber("+11234567890") .setEmailVerified(true) .setPassword("newPassword") .setDisplayName("Jane Doe") .setPhotoUrl("http://www.example.com/12345678/photo.png") .setDisabled(true); UserRecord userRecord = FirebaseAuth.getInstance().updateUser(request); System.out.println("Successfully updated user: " + userRecord.getUid());
Python
user = auth.update_user( uid, email='user@example.com', phone_number='+15555550100', email_verified=True, password='newPassword', display_name='John Doe', photo_url='http://www.example.com/12345678/photo.png', disabled=True) print(f'Sucessfully updated user: {user.uid}')
Go
params := (&auth.UserToUpdate{}). Email("user@example.com"). EmailVerified(true). PhoneNumber("+15555550100"). Password("newPassword"). DisplayName("John Doe"). PhotoURL("http://www.example.com/12345678/photo.png"). Disabled(true) u, err := client.UpdateUser(ctx, uid, params) if err != nil { log.Fatalf("error updating user: %v\n", err) } log.Printf("Successfully updated user: %v\n", u)
C#
UserRecordArgs args = new UserRecordArgs() { Uid = uid, Email = "modifiedUser@example.com", PhoneNumber = "+11234567890", EmailVerified = true, Password = "newPassword", DisplayName = "Jane Doe", PhotoUrl = "http://www.example.com/12345678/photo.png", Disabled = true, }; UserRecord userRecord = await FirebaseAuth.DefaultInstance.UpdateUserAsync(args); // See the UserRecord reference doc for the contents of userRecord. Console.WriteLine($"Successfully updated user: {userRecord.Uid}");
您可以更新下列任何使用者屬性。所有屬性皆為選填。 如果未指定屬性,屬性值將維持不變。
| 屬性 | 類型 | 說明 |
|---|---|---|
email |
字串 | 使用者的新主要電子郵件地址。請輸入有效的電子郵件地址。 |
emailVerified |
布林值 |
使用者的主要電子郵件地址是否已通過驗證。如未提供,則預設為 false。
|
phoneNumber |
字串 |
使用者的新主要電話號碼。必須是符合 E.164 規格的有效電話號碼。設為 null 可清除使用者現有的電話號碼。
|
password |
字串 | 使用者的新原始密碼 (未經過雜湊處理)。長度不得少於六個字元。 |
displayName |
字串 | null |
使用者的顯示名稱。設為 null 可清除使用者現有的顯示名稱。
|
photoURL |
字串 | null |
使用者的相片新網址。設為 null 可清除使用者現有的相片網址。如果不是 null,則必須是有效的網址。
|
disabled |
布林值 |
使用者是否已停用。true:已停用。
false:已啟用。
|
刪除使用者
您可以刪除使用者及其 uid:
Node.js
getAuth() .deleteUser(uid) .then(() => { console.log('Successfully deleted user'); }) .catch((error) => { console.log('Error deleting user:', error); });
Java
FirebaseAuth.getInstance().deleteUser(uid); System.out.println("Successfully deleted user.");
Python
auth.delete_user(uid) print('Successfully deleted user')
Go
err := client.DeleteUser(ctx, uid) if err != nil { log.Fatalf("error deleting user: %v\n", err) } log.Printf("Successfully deleted user: %s\n", uid)
C#
await FirebaseAuth.DefaultInstance.DeleteUserAsync(uid); Console.WriteLine("Successfully deleted user.");
刪除多位使用者
您也可以一次刪除多位使用者:
Node.js
getAuth() .deleteUsers([uid1, uid2, uid3]) .then((deleteUsersResult) => { console.log(`Successfully deleted ${deleteUsersResult.successCount} users`); console.log(`Failed to delete ${deleteUsersResult.failureCount} users`); deleteUsersResult.errors.forEach((err) => { console.log(err.error.toJSON()); }); }) .catch((error) => { console.log('Error deleting users:', error); });
Java
DeleteUsersResult result = FirebaseAuth.getInstance().deleteUsersAsync( Arrays.asList("uid1", "uid2", "uid3")).get(); System.out.println("Successfully deleted " + result.getSuccessCount() + " users"); System.out.println("Failed to delete " + result.getFailureCount() + " users"); for (ErrorInfo error : result.getErrors()) { System.out.println("error #" + error.getIndex() + ", reason: " + error.getReason()); }
Python
from firebase_admin import auth result = auth.delete_users(["uid1", "uid2", "uid3"]) print(f'Successfully deleted {result.success_count} users') print(f'Failed to delete {result.failure_count} users') for err in result.errors: print(f'error #{result.index}, reason: {result.reason}')
Go
deleteUsersResult, err := client.DeleteUsers(ctx, []string{"uid1", "uid2", "uid3"}) if err != nil { log.Fatalf("error deleting users: %v\n", err) } log.Printf("Successfully deleted %d users", deleteUsersResult.SuccessCount) log.Printf("Failed to delete %d users", deleteUsersResult.FailureCount) for _, err := range deleteUsersResult.Errors { log.Printf("%v", err) }
C#
DeleteUsersResult result = await FirebaseAuth.DefaultInstance.DeleteUsersAsync(new List<string> { "uid1", "uid2", "uid3", }); Console.WriteLine($"Successfully deleted {result.SuccessCount} users."); Console.WriteLine($"Failed to delete {result.FailureCount} users."); foreach (ErrorInfo err in result.Errors) { Console.WriteLine($"Error #{err.Index}, reason: {err.Reason}"); }
刪除使用者方法會傳回無法刪除的使用者失敗清單。