프로그래매틱 방식으로 사용자 관리

이 문서에서는 Identity Platform Admin SDK를 사용하여 프로그래매틱 방식으로 사용자를 관리하는 방법을 설명합니다. 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);
  });

자바

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('Successfully fetched user data: {0}'.format(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);
  });

자바

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('Successfully fetched user data: {0}'.format(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")을 호출하면 예상 사용자가 반환됩니다.

기본 이메일은 계정 연결 설정에 따라 다릅니다.

  • 동일한 이메일을 사용하는 계정 연결: 수동으로 업데이트하지 않는 한 기본 이메일은 로그인하는 데 사용된 첫 번째 이메일입니다.
  • 각 ID 공급업체에 여러 계정 만들기: 수동으로 업데이트하지 않는 한 기본 이메일은 비밀번호 사용자가 생성될 때에만 설정됩니다.

전화번호로 사용자 가져오기

사용자가 전화번호를 가지고 있다면 이 번호를 사용하여 번호를 조회할 수 있습니다.

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

자바

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('Successfully fetched user data: {0}'.format(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}");

사용자 데이터 일괄 검색

제공하는 식별자를 기반으로 사용자 목록을 검색할 수도 있습니다. uid, 이메일 또는 전화번호로 사용자를 식별할 수 있습니다. 호출 한 번에 최대 100개의 식별자를 제공할 수 있습니다. 다음과 같이 여러 유형의 식별자가 포함될 수 있습니다.

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

자바

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 또는 해당 식별자를 찾을 수 없는 이유를 나타내는 오류가 포함되어 있습니다.

사용자 나열

아래 코드는 모든 사용자를 나열하는 방법을 보여줍니다.

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

자바

// 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 필드는 최대 배치 크기를 지정합니다. 기본값 및 최댓값은 1,000입니다.

사용자 비밀번호 해시 나열

비밀번호 해시는 민감한 정보이므로 사용자에게 firebaseauth.configs.getHashConfig 권한이 없으면 Admin SDK는 이를 반환하지 않습니다. 이 권한은 사전 정의된 역할로 부여되지 않습니다. 권한을 부여하려면 다음 단계를 따르세요.

  1. firebaseauth.configs.getHashConfig 권한을 부여하는 커스텀 역할을 만듭니다.

  2. 사용자 또는 서비스 계정에 커스텀 역할을 부여합니다.

이 커스텀 역할이 있는 사용자가 이후에 listUsers()를 호출하면 passwordHashpasswordSalt 필드가 포함됩니다.

사용자 만들기

프로그래매틱 방식으로 새 사용자를 만들면 최종 사용자에게 적용되는 일부 제한이 방지됩니다. 제한 또는 비율 제한이 적용되지 않으며 이메일 및 전화번호의 일반적인 확인 절차를 우회할 수 있습니다.

새 사용자를 만들려면 다음 단계를 따릅니다.

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

자바

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('Sucessfully created new user: {0}'.format(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 문자열 사용자의 해시되지 않은 원시 비밀번호. 6자(영문 기준) 이상이어야 합니다.
displayName 문자열 사용자의 표시 이름
photoURL 문자열 사용자의 사진 URL
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);
  });

자바

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('Sucessfully updated user: {0}'.format(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 문자열 사용자의 해시되지 않은 새 원시 비밀번호. 6자(영문 기준) 이상이어야 합니다.
displayName 문자열 | null 사용자의 새 표시 이름. 사용자의 기존 표시 이름을 지우려면 null로 설정합니다.
photoURL 문자열 | null 사용자의 새 사진 URL. 사용자의 기존 사진 URL을 지우려면 null로 설정합니다. null이 아닌 경우 유효한 URL을 제공해야 합니다.
disabled 부울 사용자의 사용 중지 여부 사용이 중지된 경우 true이고 사용하는 경우 false입니다.

사용자 삭제

uid로 사용자를 삭제할 수 있습니다.

Node.js

getAuth()
  .deleteUser(uid)
  .then(() => {
    console.log('Successfully deleted user');
  })
  .catch((error) => {
    console.log('Error deleting user:', error);
  });

자바

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

자바

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('Successfully deleted {0} users'.format(result.success_count))
print('Failed to delete {0} users'.format(result.failure_count))
for err in result.errors:
    print('error #{0}, reason: {1}'.format(result.index, 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}");
}

사용자 삭제 메서드는 삭제할 수 없는 사용자에 대해 실패 목록을 반환합니다.

다음 단계