2016-06-25 16 views
10

Mi piace davvero scrivere codice con Firebase. È un ottimo back-end con una varietà di diversi set di strumenti. Ma mi manca un modo semplice per controllare un percorso per i dati aggiornati quando la persistenza è abilitata. Penso che questo non sia un caso raramente usuale, perché spesso ho bisogno che la mia app agisca in un certo modo a seconda dei dati del server più recenti, che devono essere letti solo una volta.Firebase: come utilizzare observSingleEventOfType per i dati del server più recenti quando la persistenza è abilitata?

Io di solito uso observeSingleEventOfType, ma è abbastanza inutile quando è abilitata la perisistenza, dal momento che è will never retrieve the latest server data. Che non capisco perché Dovrebbe essere aggiunta un'opzione per saltare la cache locale e cercare solo i dati del server.

La disabilitazione della persistenza risolve questo problema e observeSingleEventOfType funzionerà come previsto. Ma questo significherebbe che è necessario reimplementare tutte le funzionalità offline da solo.

Primo scenario:

// chats contain meta information about the chat like last message and count of unread messages 

let chatRef = ref.child("chats").child(receiverId).child(chatId) 
chatRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in 
    if !snapshot.exists() { 
     print("snapshot does not exist") 
     // the other side has deleted the chat 
     // now delete all messages and member objects 

     ref.child("messages").child(chatId).setValue(nil) 
     ref.child("members").child(chatId).setValue(nil) 
    } else { 
     print("snapshot exists") 
    } 
}) 

Ho anche provato chatRef.keepSynced(true) prima di osservazione per gli eventi senza fortuna. Il che non ha senso in tutte le situazioni comunque:

Secondo scenario:

func removeOlderMessages() { 
    let dateInThePast = NSDate().addDays(-30).timeIntervalSince1970 * 1000 
    self.messagesRef.queryOrderedByChild("timestamp") 
     .queryEndingAtValue(dateInThePast) 
     .observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in 
      snapshot.ref.removeValue() 
    }) 
} 

Utilizzando keepSynced qui porterebbe a scaricare tutti i messaggi in messagesRef, che non è voluto a tutti.

Quindi c'è una soluzione intelligente per questi due scenari? Qualsiasi aiuto è apprezzato.

+0

Lo stesso problema qui http://stackoverflow.com/questions/37847265/firebase-offline-store-query-not-returning-changes-in-online-store – DogCoffee

+0

Sì, abbiamo sicuramente bisogno di una soluzione per questo. Sono curioso di sapere se Firebase sta già lavorando su funzionalità che consentono questo. – MJQZ1347

risposta

3

Ok, penso di aver trovato una soluzione ragionevole per entrambi gli scenari:

Soluzione per primo scenario:

Usa transactions. Funzioneranno solo quando sei online. Il blocco completition restituirà i dati del server più recenti.

self.ref.child("chats").child(receiverId).child(chatId).runTransactionBlock({ (currentData) -> FIRTransactionResult in 
    // Actually do nothing with the retrieved data and re-submit it. 
    return FIRTransactionResult.successWithValue(currentData) 
}) { (error, success, snapshot) in 

    if let error = error { 
     print(error) 
     return 
    } else if !success || snapshot == nil { 
     return 
    } 

    // snapshot contains the latest server data 
    if !snapshot!.exists() { 
     // the other side has deleted the chat 
     // now delete all messages and member objects 

     print("snapshot doesn't exist. deleting messages and members.") 
     ref.child("messages").child(chatId).setValue(nil) 
     ref.child("members").child(chatId).setValue(nil)  
    } else { 
     print("snapshot exists. not deleting all messages and members.") 
    }  
} 

Il rovescio della medaglia è che ci vorrà molto più tempo per recuperare i dati rispetto ai observeEventType o observeSingleEventOfType.

Soluzione per secondo scenario:

Usa observeEventType(.Value). In primo luogo restituirà i dati del server cache e quindi più recenti, se disponibili. L'osservatore può essere rimosso dopo un intervallo di tempo impostato con NSTimer.

Tutto sommato queste soluzioni alternative sono ok per ora, ma una funzione per saltare la cache locale quando si utilizza observeSingleEventOfType è indispensabile.

+0

domanda veloce!Quando si scrivono dati utilizzando la transazione Firebase, se la connessione Internet del dispositivo si interrompe immediatamente dopo la scrittura, prima che una risposta sia inviata al client, il server invierà la risposta quando l'utente torna in linea? Es: internet scende subito prima di questa riga '}) {(errore, successo, istantanea) in'. Un altro scenario, internet scende immediatamente prima di 'if! Snapshot! .exists()'. Che succede qui? la tua funzione non continuerà a valutare? Quindi la tua app rimarrà in uno stato incoerente, giusto? Grazie molto – bibscy