firebase google-cloud-functions google-cloud-firestore

¿Obtener la identificación de usuario de un disparador de Firestore en Cloud Functions para Firebase?



google-cloud-functions google-cloud-firestore (7)

Como ya se sugirió anteriormente, la solución será agregar un campo user_id con los datos en sí y luego leerlo en el servidor.

El inconveniente de este enfoque será una laguna de seguridad. Como no estamos verificando la identificación de usuario en el servidor, cualquier otro usuario podrá suplantar a otros usuarios enviando su identificación con los datos.

Para aplicaciones críticas de seguridad, la solución para esto será usar reglas de seguridad para verificar que se ha enviado el user_id correcto con los datos

allow write: if resource.data.user_id == request.auth.uid;

En el siguiente ejemplo, ¿hay alguna forma de obtener la identificación de usuario (uid) del usuario que escribió a ''Offers / {offerId}''? Traté de hacer lo descrito here pero no funciona en Firestore.

exports.onNewOffer = functions.firestore .document(''offers/{offerId}'') .onCreate(event => { ... });


De qué se trata snap._fieldsProto.uid.stringValue

Ejemplo:

exports.hello = functions.firestore.document(''hello/{worldId}'').onCreate((snap, context) => { console.log(snap._fieldsProto.uid.stringValue) });


Esto debería funcionar:

exports.newMessage = functions.firestore .document(''groups/messages/{messageId}'') .onCreate((snap, context) => { var fromId = snap.data().fromId;


Estuve luchando sobre esto por un tiempo y finalmente contacté al Soporte de firebase:

event.auth.uid no está definido en el objeto de evento para los desencadenantes de la base de datos del event.auth.uid de incendios. (Funciona para los desencadenadores de bases de datos en tiempo real)

Cuando console.log(event) no puedo encontrar ninguna auth en la salida.

La respuesta oficial de soporte:

Lo sentimos, la autenticación aún no se ha agregado en el SDK de Firestore. Lo tenemos listado en las siguientes características.

Esté atento a nuestras notas de lanzamiento para cualquier actualización adicional.

Espero que esto ahorre a alguien unas horas.


Hasta que esto se agregue a las funciones de firestore, una solución alternativa es agregar user_id como campo al crear un documento y luego eliminarlo. Luego puede tomarlo en la función onCreate y luego, después de usarlo para lo que lo necesita, mientras aún está en la función, simplemente elimine el campo de ese documento.



Resumen de cómo resolví esta / una solución viable:

En el cliente

Agregue el uid del usuario conectado / actual (por ejemplo, como creatorId ) a la entidad que está creando. Acceda a este uid almacenando el objeto de usuario firebase.auth().onAuthStateChanged() en el estado de su aplicación.

En Firebase Firestore / Database

Agregue una regla de seguridad para create para validar que el valor de creatorId proporcionado por el cliente es el mismo que el del usuario autenticado; Ahora sabe que el cliente no está falsificando el creatorId y puede confiar en este valor en otro lugar.

p.ej

match /entity/{entityId} { allow create: if madeBySelf(); } function madeBySelf() { return request.auth.uid == request.resource.data.creatorId; }

En funciones de Firebase

Agregue un activador onCreate a su tipo de entidad creado para usar el creatorId proporcionado por el cliente y ahora validado para buscar la información de perfil del usuario creador y asociar / agregar esta información al nuevo documento de entidad.

Esto se puede lograr mediante:

  1. Crear una colección de users y documentos de user individuales cuando se crean nuevas cuentas, y llenar el nuevo documento de user con campos útiles para la aplicación ( displayName ejemplo, displayName ). Esto es necesario porque los campos expuestos por el sistema de autenticación de Firebase son insuficientes para los usos de las aplicaciones de consumo (por ejemplo, displayName y avatarURL no están expuestos), por lo que no puede confiar en buscar la información del usuario de esa manera.

    por ejemplo (usando ES6)

import * as functions from ''firebase-functions'' import * as admin from ''firebase-admin'' const APP = admin.initializeApp() export const createUserRecord = functions.auth.user() .onCreate(async (userRecord, context) => { const userDoc = { id: userRecord.uid, displayName: userRecord.displayName || "No Name", avatarURL: userRecord.photoURL || '''', } return APP.firestore().collection(''users'').doc(userRecord.uid).set(userDoc) })

  1. Ahora que tiene un valor creatorId validado y objetos de user útiles, agregue un activador onCreate a su tipo de entidad (o todas sus entidades creadas) para buscar la información del usuario creador y agregarla al objeto creado.

export const addCreatorToDatabaseEntry = functions.firestore .document(''<your entity type here>/{entityId}'') .onCreate(async (snapshot, context) => { const userDoc = await APP.firestore().collection(''users'').doc(snapshot.data().creatorId).get() return snapshot.ref.set({ creator: userDoc.data() }, { merge: true }) })

Esto claramente lleva a una gran cantidad de datos de información de usuario duplicados en todo su sistema, y ​​hay un poco de limpieza que puede hacer (''creatorId` está duplicado en la entidad creada en la implementación anterior), pero ahora es muy fácil de mostrar quién creó qué a través de su aplicación y parece ser ''la forma de Firebase''.

Espero que esto ayude. He descubierto que Firebase es súper sorprendente en algunos aspectos y hace que algunas cosas normalmente fáciles (como esta) sean más difíciles de lo que deberían ser; a fin de cuentas, aunque soy un gran admirador.