Pregunta Estructuración de datos para la aplicación de chat en Firebase


Estoy siguiendo la guía de Firebase para estructuración de datos para una aplicación de chat. Sugieren la estructura como se ve a continuación.

{
  // Chats contains only meta info about each conversation
  // stored under the chats's unique ID
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
    },
    "two": { ... },
    "three": { ... }
  },

  // Conversation members are easily accessible
  // and stored by chat conversation ID
  "members": {
    // we'll talk about indices like this below
    "one": {
      "ghopper": true,
      "alovelace": true,
      "eclarke": true
    },
    "two": { ... },
    "three": { ... }
  },

  // Messages are separate from data we may want to iterate quickly
  // but still easily paginated and queried, and organized by chat
  // converation ID
  "messages": {
    "one": {
      "m1": {
        "name": "eclarke",
        "message": "The relay seems to be malfunctioning.",
        "timestamp": 1459361875337
      },
      "m2": { ... },
      "m3": { ... }
    },
    "two": { ... },
    "three": { ... }
  }
}

¿Cómo estructurar mis datos de usuario para que pueda mostrar fácilmente una lista de todos los chats de los que forman parte y para cada uno de ellos mostrar el último mensaje y la marca de tiempo? Si hago la siguiente estructura:

   "users": {
    "ghopper": {
      "name": "Gary Hopper",
      "chats": {
          "one: true",
          "two": true
      }
    },
    "alovelace" { ... }
  },

Puedo obtener fácilmente una lista de cada grupo de chat para un usuario específico, por ejemplo, ghopper, haciendo (en forma rápida):

ref.child("users").child("ghopper").child("chats").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
  //do something with data
}

Sin embargo, no tendré el lastMessage y la marca de tiempo en esta instantánea. ¿Qué debo hacer para acceder a esta información?

  • ¿Duplicar todos estos datos para cada usuario? es decir, agregar usuarios / ghopper / chats / one / {"lastMessage": "ghopper: error de relé encontrado. Causa: polilla.", "marca de tiempo": 1459361875666}
  • Realice una consulta para "chats / specificGroupId" para cada conversación en la que el usuario es parte (agregando múltiples listas).
  • De alguna otra manera?

12
2018-05-29 20:34


origen


Respuestas:


¿Cómo estructurar mis datos de usuario para que pueda mostrar fácilmente una lista de   todos los chats de los que forman parte y para cada uno de ellos muestran el   último mensaje y fecha y hora.

Cambie la estructura de los chats un poco agregando usuarios que están en el nodo de chat

"chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
      users
       uid_1: true
       uid_3: true
    },
    "two": { ... },

A continuación, puede realizar consultas profundas para todos los chats de los que forma parte un usuario en particular; esto devolverá los chats en los que uid_3 participa.

chatsRef.queryOrderedByChild("users/uid_3").queryEqualToValue(true)
     .observeSingleEventOfType(.Value, withBlock: { snapshot in

     //.Value can return multiple nodes within the snapshot so iterate over them
     for child in snapshot.children {
          let lastmsg = child.value["lastMessage"] as! String
          let timestamp = child.value["timestamp"] as! String
          print(lastmsg)
          print(timestamp)
     }     
})

Tenga en cuenta que cada usuario de firebase tiene una identificación de usuario discreta obtenida cuando el usuario se crea a través de auth.uid. Esto debería (generalmente) ser utilizado como la clave para cada usuario.


17
2018-06-01 22:10



En el bloque donde tienes una lista de todos los chats en los que se encuentra un usuario, puedes hacer:

var dictionary: [String: Long]   
var lastMessage: String 
for chat in listOfChatsUserIsIn
    ref.child("chats").child("\(chat)").child("lastMessage").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        lastMessage = snapshot
        ref.child("chats").child("\(chat)").child("timestamp").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
            //add timestamp and last message to dictionary
        }
    }

No sé cuán correcta es mi sintaxis. Aún estoy aprendiendo firebase. Pero, creo que esta es básicamente tu segunda sugerencia. No sé de qué otra forma obtendría la información. Sin embargo, este sería O (2n) que no está mal.

[[Actualización 1]]

Estaba siendo flojo con mi código. Puse lastMessage = snapshot para guardarlo y poder agregarlo al diccionario en el siguiente bloque.

En cuanto a que Firebase sea asincrónico. Creo que esto funcionaría siempre que use la marca de tiempo o el mensaje como clave y el otro como valor en el diccionario. Puede estar fuera de servicio, pero siempre puede ordenarlo por marca de tiempo más tarde. Aunque, sí, esto probablemente no sea la mejor práctica.

Jay, me gusta tu solución. ¿No tendrías que incluir también uid_2: false?

Desafortunadamente, parece que ambas estructuras de base de datos crecen en n ^ 2 como usuarios -> inf y como chats -> inf.


2
2018-06-01 12:29