Acelerar la obtención de posts para mi aplicación de networking social mediante el uso de la consulta en lugar de observar un solo evento repetidamente

Tengo una serie de keys que llevan a publicar objects para mi networking social como so / posts / id / (publicar información)

Cuando carga las publicaciones que cargué / posts / 0 y luego / posts / 1 etc usando el método observeSingleEventOfType (.Value).

Utilizo un lazyTableView para cargar 30 a la vez y es bastante lento. ¿Hay alguna manera de que pueda usar uno de los methods de consulta u otra forma de hacerlo más rápido, incluso si tengo que reestructurar los datos en mi tree JSON?

Vengo de Parse re-implementando mi aplicación y hasta ahora la experiencia ha sido bastante buena. Solo que estoy un poco atrapado. 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 function recursiva funciona esencialmente obteniendo el valor para el número de key i de la base de firebase. Si es NSNULL, sabe que es la última publicación posible para cargar y nunca más. Si NSNULL no recibe un golpe, pero i% 29 == 0, vuelve como un caso base, de modo que solo se cargan 30 publicaciones a la vez (0 indexadas). Cuando establezco doneLoading a true tableView.reloadData() se llama usando un observador de propiedad.

Aquí hay una muestra de lo que la colección que estoy buscando parece

 "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 .

Cargando muchos elementos de Firebase no tiene que ser lento, ya que puede canalizar las requestes. Pero su código lo está haciendo imposible, lo que de hecho conducirá a un performance subóptimo.

En su código, solicita un artículo del server, espere a que ese artículo regrese y luego cargue el siguiente. En un diagtwig de secuencia simplificado que se parece a:

 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, espera 30 veces el time de ida y vuelta y 30 veces el time que tarda en cargar los datos del disco. Si (en aras de la simplicidad) decimos que las giras tardan 1 segundo y cargar un elemento del disco también toma un segundo, al less 30 * (1 + 1) = 60 segundos.

En las aplicaciones de Firebase obtendrá un performance mucho mejor si envía todas las requestes (o al less 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 de nuevo una ida y vuelta de 1 segundo y 1 segundo de carga, estás esperando 30 * 1 + 1 = 31 segundos.

Entonces: todas las requestes pasan por la misma connection. Dado que, la única diferencia entre get(1) , get(2) , get(3) y getAll([1,2,3]) es una sobrecarga para los frameworks.

Configuré un jsbin para demostrar el comportamiento . El model 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')) ); } 

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