Firebase: ¿Cuál es la mejor estructura de back-end para la aplicación de mensajería? (Swift / iOS)

¡Buena pregunta!

Construiría 2 clases de objetos: Mensaje y Usuario. Conectaría a los usuarios entre sí, a través de sus números de teléfono móvil, por ejemplo, para controlar quién puede enviar mensajes a quién.

El objeto Mensaje y la tabla de la base de datos solo serían un almacén de respaldo. Los mensajes reales se enviarán a través de notificaciones push, porque son instantáneos, y luego, cuando se abre la aplicación (o en segundo plano), los mensajes en una conversación particular se cargarán desde la base de datos.

Como mínimo, un objeto de mensaje debe contener “from_user”, “to_user”, una marca de tiempo y el contenido del mensaje.

Por supuesto, podría preguntarse cuál es la forma más eficiente de estructurar su back-end. Puede imaginar que los campos relacionales, como las conexiones de amigo a amigo y “este mensaje pertenece al usuario X y al usuario Y” son costosos de consultar a mayor escala.

En ese caso, aunque depende exactamente de qué escala esté trabajando, le sugiero que organice mensajes alrededor de objetos de conversación.

Cuando el usuario A inicia una conversación de mensajería con el usuario B, se crea un objeto de conversación. El usuario B recibe la ID del objeto de conversación, y ambos usuarios comienzan a enviar mensajes al hilo de conversación. Ambos usuarios se mantienen actualizados en la conversación mediante push and pull.

Dado que el objeto Conversación no contiene ningún dato relacional, porque el usuario A y B “acuerdan” una ID de conversación, y dado que la conversación no se ordenará o indexará en el lado del servidor, en teoría debería ser más rápido que pesado. datos relacionales para consultar.

EDITAR: No creo que esta pregunta tuviera “Firebase” cuando la respondí. Eso cambia las cosas …

Firebase es NoSQL, lo que significa que tendrá que desnormalizar su base de datos, y no puede confiar mucho en consultas relacionales, búsquedas o tablas de unión.

Construiría un árbol simple, como este:

  • / users / {$ uid} / {$ uid2} / {$ key} / [messages]

La raíz es / usuarios, el primer $ uid es la identificación del usuario actual y el segundo $ uid2 es la identificación del usuario con el que estoy chateando. Abrir una conversación es simplemente abrir el árbol en {$ uid2}.

El chat grupal ni siquiera necesita ser relacional, si está de acuerdo con copiar nuevos mensajes en el conjunto individual de mensajes de cada usuario en ese grupo. De lo contrario, podría simplemente hacer: / groups / {$ key} / [messages] y almacenar una referencia a todos los grupos en los que se encuentra un usuario como / users / {$ uid} / groups / {key} = true. Cuando un usuario abre un grupo, simplemente inicia la consulta en / groups / {$ key} y carga todos los mensajes.

Un malentendido común sobre Firebase es que es un buen sistema de base de datos de propósito general, como el antiguo Parse o el nuevo Parse Server. No lo es: Firebase suele ser útil cuando necesita datos no relacionales, en tiempo real. Ideal para una aplicación de chat, aplicación de lista de tareas, pero no tan bueno para las redes sociales, por ejemplo.

Desarrollé un marco de mensajería de código abierto para iOS y Android que usa Firebase como back-end. Puedes ver el proyecto en Github. Puedo decirte la estructura exacta que usamos. En el nivel más básico, tenemos tres entidades centrales:

  • Usuario
  • Hilo
  • Mensaje

El usuario tiene una relación de muchos a muchos con el hilo y el hilo tiene una relación de 1 a muchos con el mensaje.

En un entorno sin SQL, no podemos definir estas relaciones automáticamente, por lo que debemos estructurar los datos cuidadosamente para poder hacer conexiones entre entidades. Primero definimos dos ramas en la base de datos:

usuarios /
trapos/

Si queremos poder hacer referencia a una entidad, debería tener su propia sucursal. Si una entidad es hija de otra entidad, se puede agregar dentro de esa rama de entidades.

A continuación podemos enumerar las entidades por ID.

usuarios / 1 / Ben
usuarios / 2 / John

Si quisiéramos acceder a los datos de Ben, ahora tenemos una forma lógica de formular la ruta:

[tipo de entidad] / [id de entidad]

Ahora veamos hilos y mensajes:

hilos / [id de hilo] / mensajes / [id de mensaje] / [detalles del mensaje]
/ [detalles del hilo]

Los mensajes se almacenan dentro de la rama del hilo formando una nueva rama. También podríamos agregar una rama para almacenar metadatos sobre el hilo.

Para acceder a una lista de mensajes para el hilo 1, usaríamos la ruta:

hilos / 1 / mensajes

Ahora necesitamos vincular hilos a usuarios y usuarios a hilos. Para hacer esto, cree una nueva rama en cada uno:

hilos / [id de hilo] / mensajes / [id de mensaje] / [detalles del mensaje]

/ [detalles del hilo]
/ usuarios / [identificación de usuario]

usuarios / [id de usuario] / hilos / [id de hilo]
/[Detalles de usuario]

Entonces, para obtener una lista de usuarios que están en un hilo 1, usaría:

hilos / 1 / usuarios

Y para obtener una lista de hilos para el usuario 1, usaría:

usuarios / 1 / hilos

Luego puede recorrer esta lista y crear una ruta para cada hilo y luego obtener los detalles del hilo.

Aquí hay una captura de pantalla de Firebase del sistema de chat:

Trabajo para una empresa de desarrollo de aplicaciones a medida que se especializa en mensajería instantánea. Llevamos más de 3 años desarrollando aplicaciones y proyectos de chat y Firebase de usuario para la mayoría de nuestros proyectos. Revisaré cómo hemos estructurado los datos en nuestras bases de datos.

Que datos

Primero echemos un vistazo a lo que necesitamos hacer un seguimiento. Hay tres cosas principales que necesitamos guardar y monitorear: chats (hilos), usuarios y mensajes. Podemos enfocarnos razonablemente en hilos y usuarios, ya que los mensajes siempre estarán asociados con un hilo de chat.

Esto significa que necesitamos tener espacio en nuestra base de datos para poder almacenar y encontrar los datos que necesitamos. Para hacer esto, creamos sucursales en Firebase para almacenar estos datos. En el siguiente ejemplo, puede ver que también estamos rastreando la ubicación y una clave de búsqueda para los usuarios.

Puede ver una lista de usuarios arriba. Los hemos almacenado usando su ID de entidad y luego almacenamos más información para cada usuario en la base de datos.

Esta es la clave para crear una base de datos de Firebase para un chat: debe poder escribir información en la base de datos y también recuperarla con la misma facilidad.

Por ejemplo, si quisiéramos obtener la información de un usuario, podemos hacer una consulta en la siguiente ruta:

geochat_backendless2 -> users -> userEntityID

Esto nos devolvería un diccionario de usuario de sus datos que podríamos usar para completar su perfil.

Puedes ver que hacemos algo similar para los hilos:

Subimos cada subproceso al área de subprocesos de la base de datos y utilizamos su ID de entidad para rastrear cada subproceso. Luego almacenamos los detalles de cada hilo. Ahora podemos ver quién creó el hilo y también otra información útil (podemos ordenar los hilos por fecha usando el último mensaje agregado).

También agregamos una variedad de mensajes a cada conversación. Cada rama de mensaje contiene información sobre el mensaje, lo que significa que podemos descargar fácilmente la rama y mostrar todos los mensajes enviados, también hacemos un seguimiento de quién publicó el mensaje para poder vincular al usuario si es necesario.

Observadores en Firebase

Otra razón para esta estructura se debe a la naturaleza de Firebase. Para saber cuándo ha cambiado la información, observamos ciertas ramas en una base de datos. Esto hace que sea muy importante dividir los diferentes tipos de datos en áreas relevantes. Si miro la rama de usuario, puedo ver si se ha agregado un nuevo usuario, al igual que ver la rama de mensajes para una conversación de usuario específica.

No voy a entrar en demasiados detalles, ya que con suerte esto te dará una idea de una estructura de datos eficiente para una aplicación de mensajería instantánea con Firebase. La clave es almacenar su información en algún lugar que pueda descargarse fácilmente con su aplicación.

Finalmente, mi compañía ha lanzado chats de código abierto para iOS y Android que usan Firebase. Se publican en una licencia MIT, lo que significa que puede modificar y usar el código tanto como desee. Si descarga el código y configura una cuenta de Firebase, podrá ver cómo fluyen los datos, lo que podría ser útil para comprender el proceso.

El ChatSDK también está extremadamente bien escrito, por lo que generalmente recomendamos que las personas lo usen en lugar de desarrollar uno desde cero. Es gratis y funciona directamente, por lo que esta suele ser una solución mucho más eficiente.