Firebase-tools: Agregar el emulador de autenticación de base de fuego al conjunto de emuladores

Creado en 26 sept. 2019  ·  66Comentarios  ·  Fuente: firebase/firebase-tools

¿Es posible emular la API de autenticación para un desarrollo local más rápido y pruebas de extremo a extremo? Con el emulador de Firestore, no tenemos que crear diferentes proyectos para diferentes entornos (desarrollo, pruebas, preparación, producción), solo podemos usar el emulador, generar datos desde archivos JSON en modo de observación para el desarrollo o sembrar para cada caso de prueba, etc. Para poder escribir una prueba de extremo a extremo que tenga un inicio de sesión de usuario, navegación basada en el rol y luego alguna acción, tenemos que crear un proyecto separado para aislar a los usuarios de prueba, y también inicializar y borrar los usuarios allí. para cada caso de prueba.

emulator-suite feature request

Comentario más útil

Estamos trabajando duro en un emulador de autenticación completa que, con suerte, será lo que
todos quieren. No puedo ofrecer una línea de tiempo en este momento, pero es una prioridad alta
para nosotros.

El viernes 22 de mayo de 2020 a las 8:12 a.m., ChuckB [email protected] escribió:

@samtstern https://github.com/samtstern Cualquier progreso u otro
solución a este problema / característica? Necesito (1) setEmulatedUser para trabajar con el
el emulador de Cloud Firestore para poder realizar pruebas manuales localmente.

Por tu comentario: el 17 de octubre de 2019
_Creo que claramente (2) es la historia correcta, pero estaba tratando de tener una idea de
cuántas personas estarían contentas con (1) ya que es sustancialmente más sencillo
implementar y mantener.

(1) Inicie sesión para usar servicios como Firestore o Realtime Database sin
creando realmente usuarios reales. Ahora mismo eso es como algo así
setEmulatedUser resolvería. Solo te permitiría tener una autenticación falsa
token localmente que los emuladores aceptarían pero sería rechazado por
pinchar. Más seguridad, más aislamiento, etc._

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-632660684 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ACATB2Q4LV7NXMQFEALNPXLRSZT25ANCNFSM4I27PTFA
.

Todos 66 comentarios

@vladimirdjurdjevic ¡ gracias por plantear esto! Esto está en nuestra lista de cosas por hacer, pero aún no hemos decidido cuánto del servicio de autenticación emular y la mejor estrategia para hacerlo. Ciertas cosas (como la autenticación anónima) son muy fáciles de emular, mientras que otras (como la autenticación por SMS) son muy difíciles.

¡Pero definitivamente queremos habilitar el caso de uso de un extremo a otro que mencionaste!

Pregunta: ¿le resultaría útil si hubiera una biblioteca que le permitiera simular localmente a un usuario de Firebase para usarlo con los emuladores? Algo como:

firebase.auth().setEmulatedUser({
   uid: 'abc123',
   // ...
});

@samtstern ¿La llamada a setEmulatedUser() también activaría funciones de nube emuladas de functions.auth.user().onCreate() ? Si es así, sería muy útil.

@samtstern Eso ayudaría a algunos escenarios de prueba con seguridad, pero aún requiere una instancia real para el desarrollo. Mi idea es evitar la creación de múltiples proyectos de base de fuego para diferentes entornos y poder desarrollar localmente (quizás fuera de línea). Otro enfoque sería admitir diferentes entornos para los servicios. Si pudiéramos crear diferentes entornos para, digamos, firestore y auth bajo el mismo proyecto, se resolverían muchos problemas. Sé que puedo crear proyectos por entorno, pero eso es un verdadero dolor de cabeza. Configurar todos los entornos, replicar datos, etc. Idealmente, me gustaría poder crear un proyecto de base de fuego, y si necesito datos ficticios para pruebas manuales, podría simplemente crear un entorno de prueba para firestore y cargar datos allí.

@noelmansour buena pregunta! Eso no sería demasiado difícil de hacer, probablemente querríamos dos llamadas diferentes como signInAsEmulatedUser y signUpAsEmulatedUser donde solo el segundo activa la función.

@vladimirdjurdjevic está totalmente de acuerdo en que lo mejor es un emulador con todas las funciones. ¿Podría explicar qué cosas necesitaría de una "instancia real para el desarrollo" que no se resuelven al poder configurar el usuario localmente?

Pregunta: ¿le resultaría útil si hubiera una biblioteca que le permitiera simular localmente a un usuario de Firebase para usarlo con los emuladores?

Realmente útil, ayudaría mucho.
En este momento solo estoy configurando en true la función de regla que valida al usuario registrado cada vez que tengo que probar algo localmente, es bastante inseguro pero probablemente lo más simple que puedo hacer sin un usuario actual emulado.

Sí, esto sería increíblemente útil.

También me gustaría hacer una prueba unitaria functions.auth.user().onCreate() . Supongo que en este momento la mejor solución es, esencialmente, exportar la función de devolución de llamada que se pasa a onCreate y proporcionarle un objeto user falso.

Para ese tipo de prueba unitaria, consulte firebase-functions-test
biblioteca, que le ayuda a invocar sus controladores de funciones con datos simulados.

El domingo 13 de octubre de 2019 a las 5:44 a.m., Daniel K. [email protected] escribió:

También me gustaría probar la unidad functions.auth.user (). OnCreate (). I
supongamos que en este momento la mejor solución es, básicamente, exportar devolución de llamada
función transmitida onCreate y proporcionarle un objeto de usuario falso.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/firebase/firebase-tools/issues/1677?email_source=notifications&email_token=ACATB2QYJLX2LNVDTWJV25TQOMJ4VA5CNFSM4I27PTFKYY3PNVWWK3TUL52HS4DFVREXWH3WK3TUL52HS4DFVREXWG43WZMVBC ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ACATB2SO3IR6UB73F4EMZPTQOMJ4VANCNFSM4I27PTFA
.

@samtstern ¿ Eso realmente funciona junto con el emulador Firestore? Basándome en esto, tengo la impresión de que tiene un propósito diferente.

image
https://firebase.google.com/docs/functions/unit-testing#initializing

Ciertamente no quiero el modo en línea para las pruebas unitarias, eso sería lento. Y no estoy seguro de poder acceder al emulador de Firestore mediante "stubbing".

@FredyC gracias por señalar esos documentos. Las palabras utilizadas son confusas porque los "modos" no son un interruptor que pueda habilitar, solo describen estrategias que puede tomar.

Si tuviera que iniciar el emulador Firestore junto con sus pruebas unitarias, su código definitivamente podría conectarse a él. Si configura la variable de entorno FIRESTORE_EMULATOR_HOST , el SDK de Firebase Admin se conectará automáticamente al emulador de Firestore ( firebase emulators:exec hace esto por usted).

@samtstern Todavía tengo problemas para conectar puntos y ¿cómo me va a ayudar todo eso a probar functions.auth.user().onCreate() ? Quiero decir que es genial que las funciones se conecten al emulador en lugar de a una versión de producción, pero eso es solo Firestore, ¿verdad? ¿Cómo invoco la creación de usuarios a partir de las pruebas para tener realmente el código de función para activar?

Parece haber algún método críptico makeUserRecord en la prueba de funciones de base de fuego mencionada, pero no tiene mucho sentido cómo funcionaría o cómo usarlo realmente.

Intenté llamar a auth.createUserWithEmailAndPassword() desde el paquete @firebase/testing , pero eso se queja de una clave API no válida, así que supongo que funcionaría solo con la versión en línea.

Cuando busco en org esa variable env que mencionaste, solo está en tres lugares y ninguna parece ser relevante para la autenticación. A menos que esté oculto por alguna concatenación de cadenas.

También he estado navegando por https://github.com/firebase/functions-samples pero no encontré ejemplos de pruebas unitarias allí.

¿Puedes darle algún sentido a esto? :)

También tengo otro caso, algo opuesto, donde el código de la función en la nube usa admin.auth().getUserByEmail() call. Sorprendentemente, no termina con el error, pero no tengo idea de cómo crearía ese usuario para que pueda ser devuelto. Excepto, por supuesto, burlarse de todo el módulo de administración, pero eso es una locura :)

@samtstern Perdón por la demora. Cuando digo instancia real, me refiero a instancia real: D Idealmente, solo quiero intercambiar la configuración en mi archivo de entorno angular para el desarrollo, y seguir implementando funciones de autenticación como mi aplicación está hablando con API real, pero en realidad el emulador se ejecuta en mi máquina, y puedo hacerlo sin conexión. Ahora, entiendo los desafíos con el envío de SMS, por ejemplo. Sería una tontería esperar que el emulador envíe SMS reales a mi teléfono, pero tal vez podrías imprimirlo en la consola (el contenido de los SMS que se enviarían). Probablemente sea más complicado que el valor con esto. Por eso creo que el simple hecho de admitir varios entornos por proyecto podría mejorar mucho las cosas. Se necesita mucho tiempo para replicar configuraciones entre múltiples proyectos para diferentes entornos. Y también es complicado administrar varias cuentas de servicio para que los scripts puedan generar datos en diferentes proyectos de Firestore. Es por eso que enseñé que si tuviéramos una plataforma de base de fuego completa emulada, podríamos usarla para cada entorno que no sea de producción y administrar solo un proyecto de base de fuego real. Pero tal vez solo admitir varios entornos por proyecto sea una mejor solución con un resultado aceptable.

@FredyC ¡ gracias por todos sus comentarios! Es realmente útil para nosotros ver cuán confuso puede ser esto. Hay dos cosas principales que la gente quiere hacer en sus pruebas relacionadas con la autenticación:

  1. Inicie sesión para utilizar servicios como Firestore o Realtime Database sin crear usuarios reales. Ahora mismo eso es lo que resolvería algo como setEmulatedUser . Solo le permitiría tener un token de autenticación falso localmente que los emuladores aceptarían pero sería rechazado por prod. Más seguridad, más aislamiento, etc.
  2. Realmente pruebe la autenticación directamente. Esto tendría algunas piezas:
    una. Un emulador de autenticación que responde a todas las llamadas API necesarias para que puedas apuntar los SDK de autenticación hacia él.
    B. Integración entre ese emulador y el emulador de funciones para que las funciones .onCreate se activen correctamente.
    C. Auto-burlarse dentro del emulador de funciones para que admin.auth() apunte al emulador Auth, tal como lo hacemos hoy para Firestore y RTDB.

Creo que claramente (2) es la historia correcta, pero estaba tratando de tener una idea de cuántas personas estarían contentas con (1) ya que es sustancialmente más simple de implementar y mantener.

@samtstern ya veo. Corríjame si me equivoco, pero ¿no está ya resuelto el (1)? Quiero decir, en las pruebas, puedo llamar a lo siguiente y el emulador de Firestore me reconocerá como ese usuario para que pueda probar las reglas de seguridad. Todavía no lo he probado, pero parece prometedor hasta ahora :)

  const app = firebase.initializeTestApp({
    projectId,
    auth: {
      uid: 'owner'
    }
  })

El (2) definitivamente suena muy útil, pero seguro que es mucho más complejo de abordar. Lamentablemente, mi conocimiento del producto completo es tan limitado que no puedo ofrecer ideas útiles aquí.

Creo que debería construirse de forma incremental. En lugar de tratar de cubrir todos los escenarios a la vez, constrúyalo basándose en casos de uso conocidos y agregue sobre la marcha. En mi opinión limitada, emular la "base de datos de usuario" junto con los activadores de funciones no parece tan difícil de hacer.

@FredyC tiene razón en que (1) está resuelto para su uso dentro de suites de prueba. Pero el otro caso de uso es en realidad conectar su aplicación Android / iOS / Web directamente al emulador para el desarrollo local. En cuyo caso no puede usar @firebase/testing .

Veo. Honestamente, sería excelente si @firebase/testing pudiera usarse multiplataforma en lugar de tener soluciones separadas. Me refiero a lo difícil que puede ser redirigir la comunicación al emulador. ¿No es el FIRESTORE_EMULATOR_HOST exactamente eso? Aunque creo que algo como FIREBASE_EMULATOR_HOST sería más apropiado si el emulador también va a tener otros servicios.

@vladimirdjurdjevic Estoy pensando, ¿no funcionaría básicamente signInWithPhone para que puedas controlar su comportamiento? Entonces no necesita preocuparse por un emulador y obtener un código SMS simulado en la consola :)

Por supuesto, entonces necesita alguna forma de autenticarse en el emulador de Firestore (y conectarse a él). Algo como lo describí en https://github.com/firebase/firebase-tools/issues/1677#issuecomment -542897671 anterior. Existe un método subyacente para generar tokens no seguros: https://github.com/firebase/firebase-js-sdk/blob/master/packages/testing/src/api/index.ts#L64. No estoy seguro de si eso funcionaría.

Por supuesto, burlarse de las bibliotecas de terceros no siempre es tan fácil, pero una vez resuelto, puede traer grandes resultados. Eventualmente, podría extraerse a alguna biblioteca para que sea más fácil en general.

También creo que estos métodos de inicio de sesión pueden arrojar una gran cantidad de códigos de error, algo de lo que las pruebas adecuadas también deberían ocuparse. Eso también es fácil de hacer burlándose.

@samtstern Extender el contexto del espacio firebase.auth() nombres setEmulatedUser parece un anti-patrón con las estrategias de emulación existentes. ¿Es posible que esa recomendación esté influenciada por la facilidad de ampliación en el lado del paquete?

En línea con los otros emuladores, esperaría que se lance un nivel de servicio de autenticación separado a través de HTTP y una configuración del lado del cliente pueda redirigir la superficie de API existente para utilizar.

Preferiría que los casos excéntricos de AuthN devuelvan errores con la API de administrador y cliente que admite mínimamente CRUD para usuarios básicos sobre el nombre de usuario / contraseña. Diablos, creo que incluso comenzar con el soporte de token personalizado en el administrador y signInWithCustomToken iría muy lejos. Tal vez implemente la fruta madura con una matriz de soporte de API publicada en los documentos.

Para el punto @FredyC , la estrategia actual para las pruebas de autenticación de integración es importar condicionalmente el @firebase/testing en el código de la aplicación para enrutarlo a la llamada personalizada initializeTestApp . Esta acción enfatiza la exclusión de paquetes en el momento de la compilación para los equipos del proyecto y también extiende las configuraciones de redireccionamiento del emulador a través de dos API de paquetes ( initializeTestApp y firestore.settings / functions.useFunctionsEmulator )

¡Hackea el planeta!

la estrategia actual para las pruebas de autenticación de integración es importar condicionalmente el @firebase/testing en el código de la aplicación para enrutarlo a la llamada personalizada initializeTestApp .

Um, estoy llamando a ese método dentro de las pruebas. El truco es que el initializeApp normal reside en index.ts que importa funciones. Se llama cuando se inicia el emulador, pero cuando se ejecutan las pruebas, es un proceso diferente y no entran en conflicto entre sí. Entonces, realmente no hay una carga de importación condicional.

Por supuesto, esto podría ser diferente para probar la autenticación en, por ejemplo. aplicación web donde el ejecutor de pruebas compartiría el proceso con el código de la aplicación. Sin embargo, con las pruebas unitarias no suele importar una aplicación completa en una prueba. El initializeApp probablemente esté hecho en algún código que no es relevante para las pruebas y no se importa en absoluto.

@FredyC acordó los usos documentados para las pruebas unitarias. Realmente estaba hablando de escenarios de aplicaciones completas donde las API divergen y las importaciones dinámicas se salen del mapa documentado.

Solo quería darte la atribución de Honestly, it would be kinda superb if @firebase/testing could be used cross-platform instead of having separate solutions . choca esos cinco digitales

@FredyC ¡ gracias por todos sus comentarios! Es realmente útil para nosotros ver cuán confuso puede ser esto. Hay dos cosas principales que la gente quiere hacer en sus pruebas relacionadas con la autenticación:

  1. Inicie sesión para utilizar servicios como Firestore o Realtime Database sin crear usuarios reales. Ahora mismo eso es lo que resolvería algo como setEmulatedUser . Solo le permitiría tener un token de autenticación falso localmente que los emuladores aceptarían pero sería rechazado por prod. Más seguridad, más aislamiento, etc.
  2. Realmente pruebe la autenticación directamente. Esto tendría algunas piezas:
    una. Un emulador de autenticación que responde a todas las llamadas API necesarias para que puedas apuntar los SDK de autenticación hacia él.
    B. Integración entre ese emulador y el emulador de funciones para que las funciones .onCreate se activen correctamente.
    C. Auto-burlarse dentro del emulador de funciones para que admin.auth() apunte al emulador Auth, tal como lo hacemos hoy para Firestore y RTDB.

Creo que claramente (2) es la historia correcta, pero estaba tratando de tener una idea de cuántas personas estarían contentas con (1) ya que es sustancialmente más simple de implementar y mantener.

@samtstern en primer lugar me gustaría tener este tipo de emulación.

Vería que no. 1 muy útil para escribir pruebas e2e. Actualmente tengo que usar una instancia real para la autenticación, mientras que puedo usar un emulador para alojamiento, reglas, firestore y funciones.

Creo que debería ser posible usar setEmulatedUser para simular al usuario de la misma manera que se hace en firebase.initializeTestApp. Debería ser posible enviar, por ejemplo, tokens personalizados y otros datos relacionados con el usuario.

También debería ser posible obtener credenciales de muestra que podrían usarse en la aplicación cliente con firebase.auth().signInWithCredential(credential)

¡Gracias @vladimirdjurdjevic por mencionar este tema! Estábamos buscando una solución desde hace casi un año.

Nos gustaría ver un emulador real por tres cosas:

  1. e2e prueba para toda la aplicación, por lo que no tenemos que crear entornos diferentes como dijo @vladimirdjurdjevic .
  2. Pruebas de integración para el backend, donde se llaman las API y el usuario debe estar validado en Firebase.
  3. Todos nuestros desarrolladores utilizan un entorno central de Firebase durante el desarrollo, lo que provoca muchas colisiones. Por supuesto, todos los desarrolladores pueden crear su propio proyecto de Firebase, pero aún necesitan administrar a sus usuarios de prueba en el panel de Firebase, lo cual no es ideal. Además, nos gustaría desarrollar nuestra aplicación fuera de línea que no es posible hoy debido a la falta de un emulador real.

Espero que nos lance algo pronto, ¡haría que su producto fuera más valioso! ¡La productividad del desarrollador es muy importante en tales servicios!

Esta parece ser una característica de la lista de deseos de muchas personas. Firebase auth parece ser el IDaaS n. ° 1 en este momento en cuanto a precios, por lo que es realmente una molestia que no pueda desarrollar localmente con Cloud Functions. ¡Espero que el equipo de FB tenga actualizaciones para nosotros pronto! 🙏

Editar: haciendo ping a

También tengo este error ... función ignorada porque el emulador de autenticación no existe o no se está ejecutando.

esto es provocado por este código:

functions.auth.user (). onDelete ()

cualquier información sobre esto ...

@dominikfoldi

Estoy de acuerdo con tus puntos. Mientras tanto, un consejo que podría ayudarte:

Por supuesto, todos los desarrolladores pueden crear su propio proyecto de Firebase, pero aún necesitan administrar a sus usuarios de prueba en el panel de Firebase, lo cual no es ideal.

Puede inicializar y administrar usuarios mediante programación utilizando el SDK de administración de firebase, por ejemplo, auth().createUser , consulte también https://firebase.google.com/docs/auth/admin/manage-users

Después de leer este hilo, creo que la gente de aquí podría encontrar útil a Foundry .

Soy uno de los cofundadores de Foundry. Foundry es una herramienta CLI que toma sus Firebase Cloud Functions y crea una copia de su aplicación Firebase de producción en nuestros servidores que actúa como su entorno de desarrollo en el que ejecuta directamente su código. No se requiere configuración.

Foundry observa sus archivos de código fuente y cada vez que guarda su código localmente, lo ejecutamos en nuestros servidores y le devolvemos los resultados en solo unos segundos. Todo es superrápido.
Usted especifica qué datos de Firestore, RealtimeDB y Auth Users deben copiarse de su aplicación de producción a través de nuestro archivo YAML para tenerlos disponibles durante el desarrollo.

 users:
      - getFromProd: 5 # Copy first 5 users from your Firebase project
      - getFromProd: ['id-1', 'id-2'] # Copy users with the specified IDs from your Firebase project

 # Copy first 3 documents from production from the collection 'userWorkspaces'
 # also add a custom document with id 'new-user-workspace' with a new data
 # format that you want to use
 firestore:
     - collection: userWorkspaces
       docs:
         - getFromProd: 3
         - id: new-user-workspace
           data: {"newDataFormat": 42}

También especifica cómo debemos activar sus funciones en la nube cuando ejecutamos su código. Funciona como un REPL para sus funciones en la nube. De esa manera, siempre estará seguro de que sus funciones en la nube funcionarán correctamente con los datos de producción y en el entorno de producción una vez que las implemente.
Además, sus funciones en la nube actúan como si estuvieran implementadas.

Estos entornos de desarrollo se crean ad-hoc una vez que inicia su sesión. Entonces, todos en su equipo operan en su propio entorno donde pueden perder el tiempo.

No quiero enviar spam a la discusión aquí, así que no dude en enviarme un correo electrónico con cualquier pregunta [email protected]
Estoy más que feliz de ayudarlo a configurar Foundry en sus proyectos, ¡solo envíeme un correo electrónico!

Sin embargo, por cómo lo describió y lo que leí en la página de inicio, ese servicio está basado en la nube.
En cambio, el emulador de Firebase funciona incluso sin conexión, de ahí su utilidad para las pruebas automáticas.

@samtstern ¿ Algún progreso u otra solución a este problema / característica? Necesito (1) setEmulatedUser para trabajar con el emulador de Cloud Firestore para poder hacer pruebas manuales localmente. Otra opción sería tener un argumento de línea de comando que establezca la identificación del usuario cuando se inicia el emulador. De esta forma, el emulador se ejecutaría con la identificación de usuario que se le pasó durante el inicio. De esta manera, las reglas podrían probarse localmente.

Por tu comentario: el 17 de octubre de 2019
_Creo que claramente (2) es la historia correcta, pero estaba tratando de tener una idea de cuántas personas estarían contentas con (1) ya que es sustancialmente más simple de implementar y mantener.

(1) Inicie sesión para utilizar servicios como Firestore o Realtime Database sin crear usuarios reales. Ahora mismo eso es lo que resolvería algo como setEmulatedUser. Solo le permitiría tener un token de autenticación falso localmente que los emuladores aceptarían pero sería rechazado por prod. Más seguridad, más aislamiento, etc._

Estamos trabajando duro en un emulador de autenticación completa que, con suerte, será lo que
todos quieren. No puedo ofrecer una línea de tiempo en este momento, pero es una prioridad alta
para nosotros.

El viernes 22 de mayo de 2020 a las 8:12 a.m., ChuckB [email protected] escribió:

@samtstern https://github.com/samtstern Cualquier progreso u otro
solución a este problema / característica? Necesito (1) setEmulatedUser para trabajar con el
el emulador de Cloud Firestore para poder realizar pruebas manuales localmente.

Por tu comentario: el 17 de octubre de 2019
_Creo que claramente (2) es la historia correcta, pero estaba tratando de tener una idea de
cuántas personas estarían contentas con (1) ya que es sustancialmente más sencillo
implementar y mantener.

(1) Inicie sesión para usar servicios como Firestore o Realtime Database sin
creando realmente usuarios reales. Ahora mismo eso es como algo así
setEmulatedUser resolvería. Solo te permitiría tener una autenticación falsa
token localmente que los emuladores aceptarían pero sería rechazado por
pinchar. Más seguridad, más aislamiento, etc._

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-632660684 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ACATB2Q4LV7NXMQFEALNPXLRSZT25ANCNFSM4I27PTFA
.

1. Inicie sesión para utilizar servicios como Firestore o Realtime Database sin crear usuarios reales. Ahora mismo eso es lo que resolvería algo como setEmulatedUser. Solo le permitiría tener un token de autenticación falso localmente que los emuladores aceptarían pero sería rechazado por prod. Más seguridad, más aislamiento, etc.

Estaría feliz con el número 1 aquí, mientras tanto

@ rishisingh-dev no es posible ejecutar un emulador de autenticación porque los emuladores de base de fuego actualmente no incluyen uno.

Pero es perfectamente posible probar funciones en la nube que involucran autenticación en ellas. Puede refactorizar la función que necesita alguna API de autenticación y simularla en las pruebas, mientras proporciona la real en el archivo de funciones de firebase. La fidelidad de su configuración de prueba es menor, pero luego se convierte en una cuestión de grado, no de tipo: solo está probando las llamadas de autenticación directamente, pero puede probar lo que espera que sean.

En esa pregunta SO sería algo como:

function sendWelcomeEmail(user) {
  console.log(user.uid);
  console.log(user.email);
  console.log(user.displayName);
}

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => sendWelcomeEmail(user));

Y en sus pruebas, llama a sendWelcomeEmail directamente para asegurarse de que hace lo que necesita.

Imagina que tienes una función en la nube más complicada llamada addFriend , donde el usuario ingresa el correo electrónico de un amigo y quieres el uid. Puede obtenerlo a través de auths getUserByEmail .

function addFriend(email, getUserByEmail ) {
  const friendUid = getUserByEmail(email);
  // do things with friendUid;
}

exports.addFriend = functions.https.onCall(async (data, context) => {
  const email = data.email;
  const getUserByEmail = (email) => admin.auth().getUserByEmail(email);
  return { res: await addFriend(email, getUserByEmail ) };
}

En la declaración fn de la nube, envía el getUserByEmail real, pero en sus pruebas envía uno falso:

async function testAddFriend() {
  const emails = {"[email protected]": "test-uid")
  const fakeGetUserByEmail = (email) => emails[email];
  addFriend("[email protected]);
  // verify the things were done with friendUid
}

No creo que esto sea significativamente diferente a probar cualquier API de terceros en una prueba unitaria. El hecho de que los emuladores de base de fuego proporcionen autenticación elimina el texto estándar de los escenarios de prueba de un extremo a otro, pero no altera significativamente las pruebas unitarias, ya que de todos modos no querría que el estado persistente se mantuviera entre las pruebas.

Me encantaría poder ejecutar esto localmente sin tener que cargarlo en la nube para verificar

export const onCreate = functions.auth.user().onCreate((user) => {
    addGravatarURLtoUserData(user.uid, user.email)
})

export const addGravatarURLtoUserData = async (uid, email) => {
    const hash = crypto.createHash("md5").update(email).digest("hex")
    await admin.database().ref(`users/${uid}`).update({ gravatarURL: uid })
}

Por cierto, ¿puedo obtener user.displayName dentro de la función onCreate?

sí, si está configurado, creo, ¿lo probaste?

Sí, devuelve nulo.
Lo probé en la nube (no localmente).

Screen Shot 2020-07-10 at 2 43 12 AM

Mi codigo esta aqui.

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  console.log(user.uid);
  console.log(user.email);
  console.log(user.displayName);
});

Interesante, bueno, no uso el nombre para mostrar, uso el nombre de visualización de los usuarios personalizados para
db en tiempo real

/**
 * updates Custom data in the realtime datastore users object, except for the username
 * <strong i="7">@param</strong> data
 * <strong i="8">@returns</strong> {Promise<void>}
 */
export async function updatePersonalData(data) {
    const { displayName } = data
    try {
        await firebase
            .database()
            .ref("users/" + firebase.auth().currentUser.uid)
            .update({
                displayName: displayName,
            })

        userDataStore.update((user) => {
            return { ...user, displayName: displayName }
        })
    } catch (e) {
        alert(e.message)
    }
}

El viernes 10 de julio de 2020 a las 10:44, rishisingh-dev [email protected]
escribió:

Sí, devuelve nulo.
Lo probé en la nube (no localmente).

[imagen: Captura de pantalla del 10 de julio de 2020 a las 2 43 12 a. m.]
https://user-images.githubusercontent.com/56976320/87140958-29f3ac80-c257-11ea-98d3-084fad619de7.png

Mi codigo esta aqui.

console.log (user.uid);
console.log (correo electrónico de usuario);
console.log (user.displayName);
}); `` `

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-656587759 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AABU35Q27EMMHYAYU5CNZR3R23PIDANCNFSM4I27PTFA
.

>

Atentamente

Nikos Katsikanis

Sí, mi objetivo principal era actualizar la base de datos con la información del usuario dentro de la función onCreate .
Pero como no puedo obtener displayName , hice una función onCallable y la hice.

Gracias.

@samtstern Estoy muy feliz de verte trabajando en esto :) Acabo de comenzar un nuevo proyecto con firebase, y la experiencia de desarrollo ya es mucho mejor (con la interfaz de usuario del emulador y la opción --inspect-functions). Espero ver el emulador de autenticación en acción :) ¡Buen trabajo!

otra de las mejores cosas es que no tengo que abrir Chrome sin seguridad

@samtstern

Dos meses después, ¿es posible ahora dar una estimación aproximada?

Nos gustaría enviar a principios del próximo año. Ahora nos enfrentamos a la decisión de si empezamos a escribir pruebas de integración contra un proyecto real o si esperamos unos meses por el emulador de autenticación. ¿Podrías ayudarnos un poco aquí?

Mejor,

Niklas

Nuestra política en Firebase es no dar estimaciones sobre cuándo se lanzará algo a menos que estemos 100% seguros. En este momento estamos trabajando duro en el emulador Auth, pero no estamos lo suficientemente cerca de terminar como para elegir una fecha de lanzamiento.

Es una de nuestras principales prioridades, pero creo que no debe esperar a que comencemos a probar su aplicación. Escriba sus pruebas contra prod hoy, cámbielas para apuntar al emulador cuando esté disponible.

Muy bien, gracias @samtstern. ¡Eso ayuda!

Algo para lo que realmente nos gustaría usar un emulador de autenticación es probar las solicitudes de Cloud Functions y Firestore que involucran reclamos personalizados en tokens de usuario. Podemos probar afirmaciones personalizadas con Firestore en el campo de juego de reglas en Firebase Console, pero un emulador de autenticación completo, teóricamente, nos permitiría hacer mucho más en la forma de pruebas cuando se trata de tokens de usuario.

Para ser claros: estamos comprometidos con un emulador de autenticación completo que emule los puntos finales de servicio reales (siempre que sea posible). Ya no estamos considerando algo liviano como sugirieron mis comentarios anteriores .

Es genial escuchar a

@fandy no lo siento, no tenemos nada que compartir todavía ...

Gracias Sam, actualmente estoy haciendo todas mis pruebas manualmente porque no es
Vale la pena el esfuerzo de escribir pruebas e2e sin simulacros de autenticación

El miércoles 26 de agosto de 2020 a las 14:32, Sam Stern [email protected] escribió:

>
>

@fandy https://github.com/fandy no lo siento, no tenemos nada que
compartir todavía ...

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-680850282 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AABU35UAQDBYEXKKINJSM43SCT6E7ANCNFSM4I27PTFA
.

-

Atentamente

Nikos Katsikanis

Para solucionar esto, experimenté con la importación de @ firebase / testing en el navegador. Eso realmente no funcionó. Esto, sin embargo, sí: mangle @ firebase / testing source para copiar el siguiente fragmento ligeramente editado:

import firebase from "firebase/app"
import * as component from "@firebase/component"
import * as util from "@firebase/util"
import { __awaiter, __generator } from "tslib"

function createUnsecuredJwt(auth) {
    // Unsecured JWTs use "none" as the algorithm.
    var header = {
        alg: 'none',
        kid: 'fakekid'
    };
    // Ensure that the auth payload has a value for 'iat'.
    auth.iat = auth.iat || 0;
    // Use `uid` field as a backup when `sub` is missing.
    auth.sub = auth.sub || auth.uid;
    if (!auth.sub) {
        throw new Error("auth must be an object with a 'sub' or 'uid' field");
    }
    // Unsecured JWTs use the empty string as a signature.
    var signature = '';
    return [
        util.base64.encodeString(JSON.stringify(header), /*webSafe=*/ false),
        util.base64.encodeString(JSON.stringify(auth), /*webSafe=*/ false),
        signature
    ].join('.');
}

function initializeApp(accessToken, options) {
    var _this = this;
    var app = firebase.initializeApp(options);
    if (accessToken) {
        var mockAuthComponent = new component.Component('auth-internal', function () {
            return ({
                getToken: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
                    return [2 /*return*/, ({ accessToken: accessToken })];
                }); }); },
                getUid: function () { return null; },
                addAuthTokenListener: function (listener) {
                    // Call listener once immediately with predefined accessToken.
                    listener(accessToken);
                },
                removeAuthTokenListener: function () { }
            });
        }, "PRIVATE" /* PRIVATE */);
        app._addOrOverwriteComponent(mockAuthComponent);
    }
    return app;
}

export function initializeTestApp(options) {
  let accessToken = undefined
  if (options.auth !== undefined) {
    accessToken = createUnsecuredJwt(options.auth)
  }
  return initializeApp(accessToken, options)
}

Ahora, en el código del navegador de su aplicación, puede importarlo y

  let app
  if (dev) {
    app = initializeTestApp({projectId: "test", auth: {uid: "testuser"}})
    app.firestore().settings({
      host: "localhost:8080",
      ssl: false,
    })
  } else {
    app = firebaseProduction.initializeApp({ firebase config here })
    app.firestore().settings({ firestore config here })
  }
  window.firebase = app

¡Eso funciona muy bien! Ahora, cuando estoy en desarrollo, tengo un usuario falso local que el emulador cree que es "testuser" (como muestra la guía de pruebas de reglas de seguridad de firestore).

Otra solución alternativa que utilizo es eliminar su autenticación (estoy usando usuarios falsos generados para las pruebas).

Ejemplo de TypeScript:

import type { User as AuthUser } from '@firebase/auth-types'
// not importing a type, but a module of types
import { auth as authTypes} from 'firebase/app'
type Auth = authTypes.Auth

export const authStub = {
    getUser(uid: string) {
        // for uids like `testuser1234uid`
        let n = uid ? uid.replace("testuser", '').replace("uid", '') : ''
        return Promise.resolve({
            uid,
            email: `test.user${n}@foo.com`,
            emailVerified: true,
            providerData: [{
                providerId: 'google.com',
                email: `test.user${n}@foo.com`,
                uid: `testuser${n}provideruid`,
                phoneNumber: null,
                displayName: `Test User ${n}`.trim(),
                photoURL: 'https://thispersondoesnotexist.com/image',
            }],
            metadata: {
                // https://firebase.google.com/docs/reference/admin/node/admin.auth.UserMetadata
                createTime: new Date().toUTCString(),
                lastSignInTime: new Date().toUTCString()
            },
            customClaims: {
                username: `testuser${n}`
            }
        })
    },
    deleteUser(uid: string) {
        return Promise.resolve()
    },
    async updateUser(uid: string, data: AuthUser) {
        let user = await this.getUser(uid)
        return { ...user, data }
    },
    setCustomUserClaims(uid: string, customUserClaims: Object): Promise<void> {
        return Promise.resolve()
    }
}

export const auth = <Auth><unknown>authStub

También modifique sus reglas ya que auth.token no se emula. Por ejemplo:

const rules = fs.readFileSync(__dirname + '/src/firebase/firestore/firestore.rules', 'utf8')
const modifiedRules =
    rules
        .replace(/request\.auth\.token\.email_verified/g, "true")
        .replace(/request\.auth\.token\.firebase\.sign_in_provider/g, "'password'")

await firebase.loadFirestoreRules({ projectId, rules: modifiedRules })

Me está funcionando muy bien. Espero eso ayude…

Si estás siguiendo este hilo y estás dispuesto a ser un probador alfa del emulador de autenticación de Firebase, sigue estos pasos:

  1. Regístrese en el programa Firebase Alpha: https://services.google.com/fb/forms/firebasealphaprogram/
  2. Envíeme un correo electrónico a [email protected] , asegúrese de enviarlo desde la dirección de correo electrónico que utilizará para las pruebas.

¡Haga esto solo si está realmente interesado en probar un emulador de etapa inicial y proporcionar comentarios! Habrá errores y algunas partes de la configuración serán difíciles, pero queremos saber qué piensa.

@samtstern ¡ Esta es una gran noticia! Me encantaría probarlo, pero iré a la producción con mi proyecto actual al final de la semana, así que no puedo permitirme jugar con él en este momento. Me inscribiré en alpha tan pronto como pueda :) Gracias por el gran trabajo.

¡El 100% querrá probar esto! tu eres el hombre Sam!

¡@samtstern deseando probarlo y ayudar en lo que pueda!

Necesito usar la función de autenticación para probar funciones localmente desde Android, el contexto de autenticación siempre es nulo

¡Buenas noticias, el Emulador de autenticación es parte de la nueva versión 8.14.0 ! 🙌🎊

Gracias por el trabajo duro, chicos y @samtstern 💪

¡muchachos geniales!

¡Solo soy el mensajero! El emulador Auth fue construido en un 99% por @yuchenshi ... y es por eso que voy a dejar que tenga el honor de cerrar este problema cuando se despierte.

¿Existe alguna documentación sobre este nuevo emulador? (cómo instalar, configurar clientes, etc.)

PD: Muchas gracias por todo el arduo trabajo en esto. Esto nos permitirá todo tipo de cosas interesantes.

@nicoburns muy pronto! Anuncio oficial, documentos y todas esas cosas buenas que llegarán muy pronto.

¡Una gran noticia! :) No puedo esperar para probarlo :)

Sé que has estado esperando esto, así que vayamos al grano:

  • El emulador de autenticación de Firebase ahora está disponible. Puede obtenerlo instalando Firebase CLI> = v8.14.0.
  • Siga la guía de Emulator Suite para comenzar y conecte sus aplicaciones .
  • Para anuncios emocionantes como este y mucho más, sintonice la transmisión en vivo de Firebase Summit AHORA MISMO. **

** Enchufe descarado: también voy a realizar una sesión sobre "Cómo configurar CI usando el paquete Firebase Emulator" más tarde hoy. Ubicar eso en el horario de la


_PD. Realmente no puedo tomar el 99% del crédito ya que Auth Emulator es, por supuesto, un trabajo en equipo. Varias personas en Firebase y los desarrolladores de Firebase (usted) también jugaron un papel importante en esto. ¡Gracias!_

@yuchenshi ¿Es posible exportar usuarios creados al salir, al igual que con el emulador firestore?

@vdjurdjevic todavía no, estamos trabajando en eso.

Este es un problema muy popular y cada actualización notifica a 50-100 personas. Dado que ahora hemos lanzado el emulador Auth, voy a bloquear este problema para futuras actualizaciones. Si tiene alguna pregunta, error o solicitud de función, inicie una nueva edición.

¿Fue útil esta página
0 / 5 - 0 calificaciones