Agiliza la obtención de publicaciones para mi aplicación de red social mediante el uso de consultas en lugar de observar un único evento repetidamente

Tengo una serie de claves que conducen a publicar objetos para mi red social como so / posts / id / (información de la publicación)

Cuando cargo los mensajes, cargo / posts / 0 y luego / posts / 1 usando el método observeSingleEventOfType (.Value).

Uso lazyTableView para cargar 30 a la vez y es bastante lento. ¿Hay alguna manera de que pueda utilizar uno de los métodos de consulta u otra forma de hacerlo más rápido, incluso si tengo que reestructurar los datos en mi árbol JSON.

Vengo de Parse reimplementando mi aplicación y hasta ahora la experiencia ha sido bastante buena. Solo esta una cosa en la que estoy un poco atascado. Gracias de antemano por la ayuda!

EDITAR:

func loadNext(i: Int) { // check if exhists let ideaPostsRef = Firebase(url: "https://APPURL") ideaPostsRef.childByAppendingPath(i.description).observeSingleEventOfType(.Value, withBlock: { (snapshot) in if i % 29 == 0 && i != 0 && !self.hitNull { return } // false if nil // true if not nil if !(snapshot.value is NSNull) { let postJSON = snapshot.value as! [String: AnyObject] print("GOT VALID \(postJSON)") let post = IdeaPost(message: postJSON["message"] as! String, byUser: postJSON["user"] as! String, withId: i.description) post.upvotes = postJSON["upvotes"] as! Int self.ideaPostDataSource.append(post) self.loadNext(i + 1) } else { // doesn't exhist print("GOT NULL RETURNING AT \(i)") self.doneLoading = true self.hitNull = true return } }) 

Esta función recursiva se ejecuta esencialmente obteniendo el valor para el número de clave i de firebase. Si es NSNULL, sabe que es la última publicación posible de cargar y nunca más. Si NSNULL no se ve afectado, pero i% 29 == 0, se devuelve como caso base, por lo que solo se cargan 30 publicaciones a la vez (0 indexadas). Cuando configuro doneLoading en true, se llama a tableView.reloadData() utilizando un observador de propiedades.

Aquí hay una muestra de cómo se ve la matriz que estoy buscando

 "ideaPosts" : [ { "id" : 0, "message" : "Test", "upvotes" : 1, "user" : "Anonymous" }, { "id" : 1, "message" : "Test2", "upvotes" : 1, "user" : "Anonymous" } ] 

Actualización: ahora también cubrimos esta pregunta en un episodio de AskFirebase .

La carga de muchos elementos de Firebase no tiene por qué ser lenta, ya que puede canalizar las solicitudes. Pero su código está haciendo esto imposible, lo que de hecho llevará a un rendimiento subóptimo.

En su código, solicita un artículo del servidor, espera a que vuelva el artículo y luego carga el siguiente. En un diagtwig de secuencia simplificado que se ve así:

 Your app Firebase Database -- request item 1 --> SL eo ra vd ei <- return item 1 -- rn g -- request item 2 --> SL eo ra vd ei rn <- return item 2 -- g -- request item 3 --> . . . -- request item 30--> SL eo ra vd ei rn g <- return item 30 -- 

En este escenario, está esperando 30 veces su tiempo de ida y vuelta + 30 veces el tiempo que lleva cargar los datos del disco. Si (en aras de la simplicidad) decimos que los viajes de ida y vuelta toman 1 segundo y cargar un artículo desde el disco también lleva un segundo por lo menos a 30 * (1 + 1) = 60 segundos.

En las aplicaciones de Firebase obtendrá un rendimiento mucho mejor si envía todas las solicitudes (o al menos una cantidad razonable de ellas) de una sola vez:

 Your app Firebase Database -- request item 1 --> -- request item 2 --> SL -- request item 3 --> eo . ra . vd . ei -- request item 30--> rn g <- return item 1 -- <- return item 2 -- <- return item 3 -- . . . <- return item 30 -- 

Si asumimos nuevamente una ida y vuelta de 1 segundo y un segundo de carga, está esperando 30 * 1 + 1 = 31 segundos.

Entonces: todas las solicitudes pasan por la misma conexión. Teniendo en cuenta que, la única diferencia entre get(1) , get(2) , get(3) y getAll([1,2,3]) es una sobrecarga para los cuadros.

Configuré un jsbin para demostrar el comportamiento . El modelo de datos es muy simple, pero muestra la diferencia.

 function loadVideosSequential(videoIds) { if (videoIds.length > 0) { db.child('videos').child(videoIds[0]).once('value', snapshot => { if (videoIds.length > 1) { loadVideosSequential(videoIds.splice(1), callback) } }); } } function loadVideosParallel(videoIds) { Promise.all( videoIds.map(id => db.child('videos').child(id).once('value')) ); } 

A modo de comparación: la carga secuencial de 64 elementos lleva 3.8 segundos en mi sistema, mientras que los carga encauzados (como hace el cliente de Firebase de forma nativa) lleva 600 ms. Los números exactos dependerán de su conexión (latencia y ancho de banda), pero la versión canalizada siempre debe ser significativamente más rápida.