¿Obtener la identificación de usuario de un activador de Firestore en Cloud Functions para Firebase?
En el siguiente ejemplo, ¿hay alguna manera de obtener la identificación de usuario (uid) del usuario que escribió en 'ofertas/{offerId}'? Intenté hacer lo que se describe aquí pero no funciona en Firestore.
exports.onNewOffer = functions.firestore
.document('offers/{offerId}')
.onCreate(event => {
...
});
Estuve luchando con esto por un tiempo y finalmente me comuniqué con el soporte de Firebase:
No event.auth.uid
está definido en el objeto de evento para los activadores de la base de datos de Firestore. (Funciona para los activadores de bases de datos en tiempo real)
Cuando console.log(event)
no puedo encontrar ninguno 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 enumerado en las siguientes características.
Esté atento a nuestras notas de la versión para obtener más actualizaciones.
Espero que esto le ahorre a alguien unas horas.
ACTUALIZAR:
El problema se solucionó y la función nunca se implementará:
Hola a todos de nuevo. Otra actualización. Se ha decidido que, lamentablemente, el soporte nativo para context.auth para los activadores de Firestore no se implementará debido a limitaciones técnicas. Sin embargo, se está trabajando en una solución diferente que, con suerte, satisfará su caso de uso, pero no puedo compartir detalles. En este foro generalmente mantenemos abiertos solo los problemas que se pueden resolver dentro del propio SDK de funciones. He mantenido este abierto porque parecía importante y quería proporcionar algunas actualizaciones sobre los errores internos que rastrean este trabajo. Ahora que se ha tomado una decisión, voy a cerrar esto. Gracias de nuevo por la paciencia de todos y lamento no tener mejores noticias. Utilice la solución alternativa a la que se hace referencia aquí .
Resumen de cómo resolví esto/una solución viable:
En cliente
Agregue el uid del usuario registrado/actual (por ejemplo, como creatorId
) a la entidad que están creando. Acceda a este uid almacenando el firebase.auth().onAuthStateChanged()
objeto Usuario en el estado de su aplicación.
En Firebase Firestore/Base de datos
Agregue una regla de seguridad para create
validar que el valor proporcionado por el cliente creatorId
sea el mismo que el uid del usuario autenticado; Ahora sabes que el cliente no está falsificando creatorId
y puede confiar en este valor en otra parte.
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 onCreate
activador a su tipo de entidad creado para usar la información proporcionada por el cliente y ahora validada creatorId
para buscar la información del perfil del usuario creador y asociar/agregar esta información al nuevo documento de entidad.
Esto se puede lograr mediante:
Crear una
users
colección yuser
documentos individuales cuando se crean nuevas cuentas y completar el nuevouser
documento con campos útiles para la aplicación (por ejemplodisplayName
). Esto es necesario porque los campos expuestos por el sistema de autenticación de Firebase son insuficientes para los usos de las aplicaciones del consumidor (por ejemplo,displayName
yavatarURL
no están expuestos), por lo que no puede confiar simplemente en buscar la información del usuario creador 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)
})
- Ahora que tiene un
creatorId
valor validado yuser
objetos útiles, agregue unonCreate
activador a su tipo de entidad (o a 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 conduce 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é en toda su aplicación, y parece ser "al estilo Firebase".
Espero que esto ayude. Descubrí 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, soy un gran admirador.