UPDATE
E 'ora possibile aggiornare più posizioni in modo atomico. Vedi this blog post per i dettagli.
var mergedUpdate = {};
mergedUpdate[ 'users/' + userId + '/widgets/' + widgetId ] = true;
mergedUpdate[ 'widgets/' + widgetId ] = widgetData;
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");
ref.update(mergedUpdate);
Questo non impone dati delle transazioni (se il valore è attualmente X, rendono Y), ma questa parte può essere spostato security rules. Per esempio, se vogliamo aggiornare due contatori, allo stesso tempo, potremmo aggiungere dichiara:
{
"counter1": {
".validate": "newData.val() === (data.val()||0)+1"
},
"counter2"1 {
".validate": "newData.val() === (data.val()||0)+1"
}
}
Ora siamo in grado di tentare lo stesso aggiornamento multi-path come sopra. Se i valori sono cambiati dall'ultima volta che li abbiamo letti dal server, il tentativo fallirà. Possiamo controllare if(error.code === 'PERMISSION_DENIED') { ... }
per vedere se l'errore è dovuto alla convalida e riprovare di conseguenza.
ORIGINALE POST
L'unico modo per farlo è quello di eseguire una transazione su un antenato comune.
Ad esempio, se si desidera aggiornare/a/b/c e/a/x/y, è possibile eseguire una transazione in/a e modificare entrambi i valori.
Lo svantaggio di questo approccio è che può essere costoso con I/O di rete, poiché tutti i dati all'interno della transazione devono essere scaricati e quindi inviati al server.
Un approccio più complicato ma potenzialmente più potente che si potrebbe prendere in considerazione è la ristrutturazione dei dati in modo che, anziché memorizzare i valori effettivi, si memorizzi una cronologia delle modifiche. Ad esempio, se si memorizzano informazioni sul saldo bancario, è possibile memorizzare una cronologia di depositi e prelievi. Poi, quando volevi ottenere il saldo, avresti riprodotto l'intera storia e calcolato il saldo finale.
La bellezza di questo approccio è che ti permette di fare aggiornamenti atomici. Ad esempio, se trasferisci denaro dall'accountA all'accountB, devi semplicemente aggiungere un elemento alla fine del log dicendo "trasferimento dall'account A all'accountB N dollars". L'aggiunta di quel singolo elemento è un'operazione atomica.
Questo è l'approccio che adottiamo con Firepad, il nostro editor di testo collaborativo.
Grazie per la risposta. Concettualmente mi piace memorizzare nuove transazioni piuttosto che aggiornare sul posto, ma penso che sia praticabile da un punto di vista delle prestazioni solo se esiste una funzionalità di materializzazione delle query. La riproduzione di tutta la cronologia sarebbe lenta. –
Non ce n'è uno (almeno non ancora), ma vediamo sicuramente come sarebbe utile! Per ora si può materializzarsi la query sul client e memorizzarlo di nuovo ad un "checkpoint" in Firebase (questo è come funziona Firepad), o si potrebbe avere un node.js o un server basato su Java in esecuzione da qualche parte come un client che si materializza Firebase è per te. –
HI! Grazie, ma l'ho appena provato e ho ricevuto un errore: "Riga 10: L'operando a sinistra di || deve essere booleano." Mi sto perdendo qualcosa? Sto usando Firebase 3.0 ... –