콘솔로 이동

사용자 가져오기

Firebase Admin SDK에서 제공하는 auth.importUsers() API를 활용하면 더 많은 권한으로 Firebase 인증에 사용자 일괄 가져오기가 가능합니다. Firebase CLI에서도 이 기능을 사용할 수 있지만, Admin SDK를 사용하면 임시 CSV 또는 JSON 파일을 만들지 않고도 프로그래매틱 방식으로 외부 인증 시스템 또는 다른 Firebase 프로젝트에서 기존 사용자를 업로드할 수 있습니다.

사용자 가져오기 API의 이점은 다음과 같습니다.

  • 다른 비밀번호 해싱 알고리즘을 사용하는 외부 인증 시스템에서 사용자를 이전할 수 있습니다.
  • 다른 Firebase 프로젝트에서 사용자를 이전할 수 있습니다.
  • 빠르고 효율적인 일괄 가져오기 작업에 맞춰 최적화되어 있습니다. 이 작업에서는 uid, email, phoneNumber 또는 다른 식별자의 중복 확인 없이 사용자를 처리합니다.
  • 기존 OAuth(Google, Facebook 등) 사용자를 이전하거나 새로운 OAuth 사용자를 만들 수 있습니다.
  • 맞춤 클레임을 통해 직접 사용자를 일괄적으로 가져올 수 있습니다.

사용량

API 호출 한 번으로 최대 1000명의 사용자를 가져올 수 있습니다. 참고로 이 작업은 속도에 맞춰 최적화되어 있으므로 uid, email, phoneNumber 및 기타 고유 식별자의 중복을 확인하지 않습니다. 기존 uid와 충돌하는 사용자를 가져오면 기존 사용자가 바뀝니다. 다른 필드가 중복된(예: email) 사용자를 가져오면 같은 값이 있는 사용자가 추가됩니다. 따라서 이 API를 사용할 때는 고유한 필드가 중복되지 않는지 확인해야 합니다.

Node.js

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

자바

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

Python

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

Go

// Up to 1000 users can be imported at once.
var users []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
	UID("uid1").
	Email("user1@example.com").
	PasswordHash([]byte("passwordHash1")).
	PasswordSalt([]byte("salt1")))
users = append(users, (&auth.UserToImport{}).
	UID("uid2").
	Email("user2@example.com").
	PasswordHash([]byte("passwordHash2")).
	PasswordSalt([]byte("salt2")))

이 예에서는 해싱 옵션이 지정되어 있어 이후 사용자가 Firebase 인증으로 로그인하려고 하면 Firebase에서 안전하게 사용자를 인증할 수 있습니다. 성공적으로 로그인하면 Firebase에서 내부 Firebase 해싱 알고리즘으로 사용자의 비밀번호를 다시 해싱 처리합니다. 아래에서 알고리즘에 따른 필수 필드에 대해 자세히 알아보세요

Firebase 인증에서는 사용자별 오류가 발생해도 제공된 전체 사용자 목록의 업로드를 시도합니다. 이 작업으로 가져오기 성공 및 실패 요약을 포함한 결과가 반환됩니다. 오류 세부정보는 실패한 사용자 가져오기 별로 반환됩니다.

Node.js

admin.auth().importUsers(userImportRecords, userImportOptions)
  .then(function(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(function(error) {
    // Some unrecoverable error occurred that prevented the operation from running.
  });

자바

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('Successfully imported {0} users. Failed to import {1} users.'.format(
        result.success_count, result.failure_count))
    for err in result.errors:
        print('Failed to import {0} due to {1}'.format(users[err.index].uid, err.reason))
except auth.AuthError:
    # 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)
}

비밀번호 해싱이 필요 없는 경우(전화번호, 맞춤 토큰 사용자, OAuth 사용자 등) 해싱 옵션을 제공하지 마세요.

HMAC 해시 비밀번호를 사용한 사용자 가져오기

HMAC 해싱 알고리즘에는 HMAC_MD5, HMAC_SHA1, HMAC_SHA256, HMAC_SHA512가 포함됩니다. 이 해싱 알고리즘의 경우 해시 서명자 키를 제공해야 합니다.

Node.js

admin.auth().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(function(results) {
    results.errors.forEach(function(indexedError) {
     console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.HMACSHA256{
	Key: []byte("secret"),
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

MD5, SHA, PBKDF 해시 비밀번호를 사용한 사용자 가져오기

MD5, SHA, PBKDF 해싱 알고리즘에는 MD5, SHA1, SHA256, SHA512, PBKDF_SHA1, PBKDF2_SHA256이 포함됩니다. 이 해싱 알고리즘의 경우 비밀번호를 해시하는 데 사용되는 0으로 끝나는 수(0~120000)를 제공해야 합니다.

Node.js

admin.auth().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(function(results) {
   results.errors.forEach(function(indexedError) {
      console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.PBKDF2SHA256{
	Rounds: 100000,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

표준 SCRYPT 해시 비밀번호를 사용한 사용자 가져오기

Firebase 인증에서는 표준 SCRYPT 알고리즘은 물론 내부적으로 수정된 버전도 지원합니다. 표준 SCRYPT 알고리즘의 경우 다음과 같은 해싱 매개변수가 필요합니다.

  • memoryCost: 해싱 알고리즘의 CPU/메모리 비용입니다.
  • parallelization: 해싱 알고리즘의 병렬 처리입니다.
  • blockSize: 해싱 알고리즘의 블록 크기(일반적으로 8)입니다.
  • derivedKeyLength: 해싱 알고리즘의 파생 키 길이입니다.

Node.js

admin.auth().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(function(results) {
    results.errors.forEach(function(indexedError) {
     console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.StandardScrypt{
	MemoryCost:       1024,
	Parallelization:  16,
	BlockSize:        8,
	DerivedKeyLength: 64,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

BCRYPT 해시 비밀번호를 사용한 사용자 가져오기

BCRYPT 해시 비밀번호의 경우 추가 해시 매개변수 및 사용자별 비밀번호 솔트가 필요 없습니다.

Node.js

admin.auth().importUsers([{
  uid: 'some-uid',
  email: 'user@example.com',
  // Must be provided in a byte buffer.
  passwordHash: Buffer.from('password-hash')
}], {
  hash: {
    algorithm: 'BCRYPT'
  }
})
  .then(function(results) {
    results.errors.forEach(function(indexedError) {
      console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
h := hash.Bcrypt{}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}

Firebase SCRYPT 해시 비밀번호를 사용한 사용자 가져오기

다른 기존 Firebase 프로젝트에서 사용자를 이전할 때는 수정된 Firebase 버전의 SCRYPT 해싱 알고리즘으로 해싱 처리된 비밀번호를 가져오는 것이 편합니다. 이 경우 원래 프로젝트의 내부 매개변수를 결정해야 합니다.

Firebase에서는 Firebase 프로젝트마다 고유의 비밀번호 해시 매개변수를 생성합니다. 이러한 매개변수에 액세스하려면 Firebase Console의 사용자으로 이동하여 사용자 테이블 목록의 오른쪽 상단에 있는 드롭다운 메뉴에서 비밀번호 해시 매개변수를 선택합니다.

이 알고리즘의 해시 옵션을 구성하는 데 필요한 매개변수는 다음과 같습니다.

  • key: 일반적으로 base64로 인코딩되는 서명자 키입니다.
  • saltSeparator: 일반적으로 base64로 인코딩되는 솔트 구분자입니다(선택사항).
  • rounds: 비밀번호를 해시하는 데 사용된 0으로 끝나는 수입니다.
  • memoryCost: 이 알고리즘에 필요한 메모리 비용입니다.

Node.js

admin.auth().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(function(results) {
    results.errors.forEach(function(indexedError) {
      console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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(
      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=b'password_hash',
        password_salt=b'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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		Email("user@example.com").
		PasswordHash([]byte("password-hash")).
		PasswordSalt([]byte("salt")),
}
b64decode := func(s string) []byte {
	b, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		log.Fatalln("Failed to decode string", err)
	}
	return b
}

// 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:           b64decode("base64-secret"),
	SaltSeparator: b64decode("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)
}

비밀번호 없이 사용자 가져오기

비밀번호 없이 사용자를 가져올 수도 있습니다. 비밀번호가 없는 사용자는 OAuth 제공업체, 맞춤 클레임, 전화번호 등을 포함한 사용자와 조합하여 가져올 수 있습니다.

Node.js

admin.auth().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(function(results) {
    results.errors.forEach(function(indexedError) {
     console.log('Error importing user ' + indexedError.index);
    });
  })
  .catch(function(error) {
    console.log('Error importing users:', error);
  });

자바

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 auth.AuthError as error:
    print('Error importing users:', error)

Go

users := []*auth.UserToImport{
	(&auth.UserToImport{}).
		UID("some-uid").
		DisplayName("John Doe").
		Email("johndoe@gmail.com").
		PhotoURL("http://www.example.com/12345678/photo.png").
		EmailVerified(true).
		PhoneNumber("+11234567890").
		CustomClaims(map[string]interface{}{"admin": true}). // set this user as admin
		ProviderData([]*auth.UserProvider{                   // user with Google provider
			{
				UID:         "google-uid",
				Email:       "johndoe@gmail.com",
				DisplayName: "John Doe",
				PhotoURL:    "http://www.example.com/12345678/photo.png",
				ProviderID:  "google.com",
			},
		}),
}
result, err := client.ImportUsers(ctx, users)
if err != nil {
	log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
	log.Println("Failed to import user", e.Reason)
}