Importa usuarios

El SDK de Firebase Admin proporciona la API de Auth.importUsers() para importar usuarios a Firebase Authentication de manera masiva y con privilegios elevados. A pesar de que esta función también se encuentra disponible en Firebase CLI, el SDK de Admin permite subir usuarios existentes de un sistema de autenticación externo o de otro proyecto de Firebase de manera programática, sin tener que crear archivos CSV o JSON intermedios.

La API de importación de usuarios ofrece las siguientes ventajas:

  • Capacidad de migrar usuarios desde un sistema de autenticación externo mediante el uso de diferentes algoritmos de hash de contraseñas.
  • Capacidad de migrar usuarios desde otro proyecto de Firebase
  • Optimización de operaciones de importaciones masivas, rápidas y eficaces Esta operación procesa a los usuarios sin buscar uid, email, phoneNumber ni otras duplicaciones de identificación.
  • Capacidad de migrar usuarios existentes o crear nuevos usuarios de OAuth (Google, Facebook, etc.)
  • Capacidad de importar usuarios con reclamos personalizados directamente y de manera masiva.

Uso

Se pueden importar hasta 1,000 usuarios en una sola llamada a la API. Ten en cuenta que esta operación está optimizada para ser rápida y no revisa uid, email, phoneNumber ni otras duplicaciones de identificador único. Si importas un usuario que coincide con un uid existente, se reemplazará el usuario existente. Si importas un usuario con cualquier otro campo duplicado (p. ej., email), se generará un usuario adicional con el mismo valor. Por consiguiente, debes asegurarte de no duplicar ningún campo único cuando uses esta API.

Node.js

// Up to 1000 users can be imported at once.
const 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'),
  },
  //...
];

Java

// 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")))

C#

//  Up to 1000 users can be imported at once.
var users = new List<ImportUserRecordArgs>()
{
    new ImportUserRecordArgs()
    {
        Uid = "uid1",
        Email = "user1@example.com",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash1"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt1"),
    },
    new ImportUserRecordArgs()
    {
        Uid = "uid2",
        Email = "user2@example.com",
        PasswordHash = Encoding.ASCII.GetBytes("passwordHash2"),
        PasswordSalt = Encoding.ASCII.GetBytes("salt2"),
    },
};

En este ejemplo se especifican las opciones de hash para que Firebase autentique de manera segura a estos usuarios la próxima vez que intenten acceder con Firebase Authentication. Tras un acceso exitoso, Firebase vuelve a generar un hash para la contraseña del usuario con el algoritmo interno de hash de Firebase. Obtén más información sobre los campos requeridos según el algoritmo que aparece a continuación.

Firebase Authentication intenta subir la lista completa de usuarios provistos, incluso cuando ocurre un error específico con un usuario. La operación arroja un resultado con el resumen de las importaciones exitosas y las importaciones con errores. Se muestran los detalles de los errores por cada importación de usuario.

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('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 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.
}

Si no se necesita generar un hash de contraseña (número de teléfono, usuario de token personalizado, usuario de OAuth, etc.), no se proporcionan las opciones de hash.

Importa usuarios mediante contraseñas scrypt con hash de Firebase

Según la configuración predeterminada, Firebase usa una versión de Firebase modificada del algoritmo de hash de scrypt para almacenar contraseñas. Importar contraseñas con hash con una scrypt modificada es útil para migrar usuarios desde otro proyecto de Firebase. Para hacerlo, el proyecto original es el que debe determinar los parámetros internos.

Firebase genera parámetros de hash de contraseña únicos para cada proyecto de Firebase. Para acceder a estos parámetros, navega hasta la pestaña Usuarios de Firebase console y selecciona Parámetros de hash de contraseña en el menú desplegable de la esquina superior derecha de la lista de usuarios de la tabla.

Estos son algunos de los parámetros requeridos para crear las opciones de hash de este algoritmo:

  • key: La clave del firmante que se proporciona, por lo general, en la codificación base64
  • saltSeparator: El separador de sal que se proporciona, por lo general, en la codificación base64 (opcional)
  • rounds: La cantidad de rondas que se usan para aplicar hash a las contraseñas
  • memoryCost: El costo de la memoria requerido para este algoritmo

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "user@example.com",
            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}");
}

Importa usuarios mediante contraseñas scrypt con hash estándar

Firebase Authentication es compatible con el algoritmo de scrypt estándar, así como con la versión modificada (arriba). Para el algoritmo estándar de scrypt, se requieren los siguientes parámetros de hash:

  • memoryCost: El costo de CPU/memoria del algoritmo de hash
  • parallelization: La paralelización del algoritmo de hash
  • blockSize: El tamaño del bloque (normalmente 8) del algoritmo de hash
  • derivedKeyLength: La longitud de clave derivada del algoritmo de hash

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "user@example.com",
            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}");
}

Importa usuarios mediante contraseñas con hash HMAC

Los algoritmos de hash de HMAC incluyen: HMAC_MD5, HMAC_SHA1, HMAC_SHA256 y HMAC_SHA512. Debes proporcionar la clave del firmante del hash para estos algoritmos de hash.

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "user@example.com",
            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}");
}

Importa usuarios mediante contraseñas con hash MD5, SHA y PBKDF

Los algoritmos de hash MD5, SHA y PBKDF incluyen: MD5, SHA1, SHA256, SHA512, PBKDF_SHA1 y PBKDF2_SHA256. Para estos algoritmos de hash, debes proporcionar el número de rondas (entre 0 y 8,192 para MD5, entre 1 y 8,192 para SHA1, SHA256 y SHA512, y entre 0 y 120,000 para PBKDF_SHA1 y PBKDF2_SHA256) utilizadas a fin de aplicar hash a la contraseña.

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "user@example.com",
            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}");
}

Importa usuarios mediante contraseñas con hash BCRYPT

Para las contraseñas con hash de BCRYPT, no se requieren parámetros hash adicionales ni sales de contraseña por usuario.

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            Email = "user@example.com",
            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}");
}

Importa usuarios mediante contraseñas con hash Argon2

Puedes importar registros de usuarios que tengan contraseñas con hash Argon2 mediante la construcción de un objeto de hash Argon2. Ten en cuenta que, actualmente, esto solo se admite en el SDK de Admin para Java.

Estos son algunos de los parámetros requeridos para crear las opciones de hash de este algoritmo:

  • hashLengthBytes: La longitud de hash deseada en bytes, proporcionada como un número entero
  • hashType: Es la variante de Argon2 que se usará (ARGON2_D, ARGON2_ID, ARGON2_I)
  • parallelism: El grado de paralelismo, proporcionado como un número entero entre 1 y 16 (ambos valores incluidos)
  • iterations: Es la cantidad de iteraciones que se realizarán, proporcionada como un número entero entre 1 y 16 (ambos valores incluidos)
  • memoryCostKib: El costo de memoria requerido para este algoritmo en kibibytes debe ser menor que 32,768
  • version: Es la versión del algoritmo Argon2 (VERSION_10 o VERSION_13). Opcional, si no se especifica, se establece de forma predeterminada en VERSION_13
  • associatedData: Son los datos asociados adicionales, proporcionados como un array de bytes, que se agregan al valor de hash para proporcionar una capa adicional de seguridad. Estos datos se codifican en Base64 antes de enviarse a la API (opcional).

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

Importa usuarios sin contraseñas

Puedes importar usuarios sin contraseñas. Puedes hacerlo junto con los usuarios que tengan proveedores OAuth, reclamos y números de teléfono personalizados, entre otros.

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)

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

C#

try
{
    var users = new List<ImportUserRecordArgs>()
    {
        new ImportUserRecordArgs()
        {
            Uid = "some-uid",
            DisplayName = "John Doe",
            Email = "johndoe@gmail.com",
            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 = "johndoe@gmail.com",
                    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}");
}