Salvataggio dei dati

Modi per salvare i dati

METTERE Scrivi o sostituisci i dati in un percorso definito , come fireblog/users/user1/<data>
TOPPA Aggiorna alcune chiavi per un percorso definito senza sostituire tutti i dati.
INVIARE Aggiungi a un elenco di dati nel nostro database Firebase. Ogni volta che inviamo una richiesta POST , il client Firebase genera una chiave univoca, come fireblog/users/<unique-id>/<data>
ELIMINA Rimuovere i dati dal riferimento al database Firebase specificato.

Scrittura di dati con PUT

L'operazione di scrittura di base tramite l'API REST è PUT . Per dimostrare il salvataggio dei dati, creeremo un'applicazione di blogging con post e utenti. Tutti i dati per la nostra applicazione verranno archiviati nel percorso di `fireblog`, all'URL del database Firebase `https://docs-examples.firebaseio.com/fireblog`.

Iniziamo salvando alcuni dati utente nel nostro database Firebase. Conserveremo ogni utente con un nome utente univoco e memorizzeremo anche il nome completo e la data di nascita. Poiché ogni utente avrà un nome utente univoco, ha senso usare PUT qui invece di POST poiché abbiamo già la chiave e non è necessario crearne una.

Usando PUT , possiamo scrivere una stringa, un numero, un booleano, un array o qualsiasi oggetto JSON nel nostro database Firebase. In questo caso gli passeremo un oggetto:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

Quando un oggetto JSON viene salvato nel database, le proprietà dell'oggetto vengono mappate automaticamente alle posizioni figlio in modo nidificato. Se andiamo al nodo appena creato, vedremo il valore "Alan Turing". Possiamo anche salvare i dati direttamente in una posizione figlio:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

I due esempi precedenti, scrivendo il valore contemporaneamente a un oggetto e scrivendoli separatamente nelle posizioni figlio, risulteranno nel salvataggio degli stessi dati nel nostro database Firebase:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

Una richiesta riuscita sarà indicata da un codice di stato HTTP 200 OK e la risposta conterrà i dati che abbiamo scritto nel database. Il primo esempio attiverà un solo evento sui client che stanno guardando i dati, mentre il secondo esempio ne attiverà due. È importante notare che se i dati esistessero già nel percorso degli utenti, il primo approccio li sovrascriverebbe, ma il secondo metodo modificherebbe solo il valore di ciascun nodo figlio separato lasciando invariati gli altri figli. PUT è equivalente a set() nel nostro SDK JavaScript.

Aggiornamento dei dati con PATCH

Utilizzando una richiesta PATCH , possiamo aggiornare bambini specifici in una posizione senza sovrascrivere i dati esistenti. Aggiungiamo il nickname di Turing ai suoi dati utente con una richiesta PATCH :

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

La richiesta di cui sopra scriverà il nickname sul nostro fantastico oggetto alanisawesome senza cancellare il name o il birthday dei bambini. Tieni presente che se avessimo emesso una richiesta PUT qui, il name e la data di birthday sarebbero stati eliminati poiché non erano inclusi nella richiesta. I dati nel nostro database Firebase ora sono così:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

Una richiesta riuscita sarà indicata da un codice di stato HTTP 200 OK e la risposta conterrà i dati aggiornati scritti nel database.

Firebase supporta anche gli aggiornamenti multi-percorso. Ciò significa che PATCH ora può aggiornare i valori in più posizioni nel database Firebase contemporaneamente, una potente funzionalità che ti aiuta a denormalizzare i tuoi dati . Usando gli aggiornamenti multi-percorso, possiamo aggiungere soprannomi sia ad Alan che a Grace contemporaneamente:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Dopo questo aggiornamento, sia Alan che Grace hanno aggiunto i loro soprannomi:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

Si noti che il tentativo di aggiornare gli oggetti scrivendo oggetti con i percorsi inclusi risulterà in un comportamento diverso. Diamo un'occhiata a cosa succede se invece proviamo ad aggiornare Grace e Alan in questo modo:

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Ciò si traduce in un comportamento diverso, vale a dire la sovrascrittura dell'intero /fireblog/users :

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

Aggiornamento dei dati con richieste condizionali

È possibile utilizzare le richieste condizionali, l'equivalente REST delle transazioni, per aggiornare i dati in base al loro stato esistente. Ad esempio, se desideri aumentare un contatore di voti positivi e vuoi assicurarti che il conteggio rifletta accuratamente più voti positivi simultanei, utilizza una richiesta condizionale per scrivere il nuovo valore nel contatore. Invece di due scritture che modificano il contatore sullo stesso numero, una delle richieste di scrittura ha esito negativo ed è quindi possibile riprovare la richiesta con il nuovo valore.
  1. Per eseguire una richiesta condizionale in una posizione, ottieni l'identificatore univoco per i dati correnti in quella posizione o l'ETag. Se i dati cambiano in quella posizione, cambia anche l'ETag. Puoi richiedere un ETag con qualsiasi metodo diverso da PATCH . L'esempio seguente usa una richiesta GET .
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    In particolare, la chiamata dell'ETag nell'intestazione restituisce l'ETag della posizione specificata nella risposta HTTP.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
    
  2. Includere l'ETag restituito nella prossima richiesta PUT o DELETE per aggiornare i dati che corrispondono specificamente a quel valore ETag. Seguendo il nostro esempio, per aggiornare il contatore a 11, o 1 maggiore del valore recuperato iniziale di 10, e fallire la richiesta se il valore non corrisponde più, utilizzare il codice seguente:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    Se il valore dei dati corrisponde a quello specificato la posizione è ancora 10, l'ETag nella richiesta PUT corrisponde e la richiesta ha esito positivo, scrivendo 11 nel database.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    
    Se la posizione non corrisponde più all'ETag, cosa che potrebbe verificarsi se un altro utente scrive un nuovo valore nel database, la richiesta non riesce senza scrivere nella posizione. La risposta di ritorno include il nuovo valore e ETag.
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
    
  3. Utilizza le nuove informazioni se decidi di riprovare la richiesta. Il database in tempo reale non riprova automaticamente le richieste condizionali non riuscite. Tuttavia, puoi utilizzare il nuovo valore e ETag per creare una nuova richiesta condizionale con le informazioni restituite dalla risposta di errore.

Le richieste condizionali basate su REST implementano lo standard HTTP if-match . Tuttavia, differiscono dallo standard nei seguenti modi:

  • Puoi fornire un solo valore ETag per ogni richiesta if-match, non più.
  • Mentre lo standard suggerisce che gli ETag vengano restituiti con tutte le richieste, Realtime Database restituisce solo gli ETag con richieste che includono l'intestazione X-Firebase-ETag . Ciò riduce i costi di fatturazione per le richieste standard.

Le richieste condizionali potrebbero anche essere più lente delle tipiche richieste REST.

Salvataggio di elenchi di dati

Per generare una chiave univoca basata su timestamp per ogni bambino aggiunto a un riferimento al database Firebase, possiamo inviare una richiesta POST . Per il percorso dei nostri users , aveva senso definire le nostre chiavi poiché ogni utente ha un nome utente univoco. Ma quando gli utenti aggiungono post del blog all'app, utilizzeremo una richiesta POST per generare automaticamente una chiave per ogni post del blog:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

Il nostro percorso dei posts ora ha i seguenti dati:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

Si noti che la chiave -JSOpn9ZC54A4P4RoqVa è stata generata automaticamente per noi perché abbiamo utilizzato una richiesta POST . Una richiesta riuscita sarà indicata da un codice di stato HTTP 200 OK e la risposta conterrà la chiave dei nuovi dati aggiunti:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

Rimozione dei dati

Per rimuovere i dati dal database, possiamo inviare una richiesta DELETE con l'URL del percorso da cui vorremmo eliminare i dati. Quanto segue eliminerebbe Alan dal percorso dei nostri users :

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Una richiesta DELETE riuscita verrà indicata da un codice di stato HTTP 200 OK con una risposta contenente JSON null .

Parametri URI

L'API REST accetta i seguenti parametri URI durante la scrittura dei dati nel database:

aut

Il parametro auth request consente l'accesso ai dati protetti dalle regole del database in tempo reale di Firebase ed è supportato da tutti i tipi di richiesta. L'argomento può essere il segreto dell'app Firebase o un token di autenticazione, di cui parleremo nella sezione relativa all'autorizzazione dell'utente . Nell'esempio seguente inviamo una richiesta POST con un parametro auth , dove CREDENTIAL è il segreto dell'app Firebase o un token di autenticazione:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

Stampa

Il parametro print ci consente di specificare il formato della nostra risposta dal database. L'aggiunta print=pretty alla nostra richiesta restituirà i dati in un formato leggibile dall'uomo. print=pretty è supportato dalle richieste GET , PUT , POST , PATCH e DELETE .

Per eliminare l'output dal server durante la scrittura dei dati, possiamo aggiungere print=silent alla nostra richiesta. La risposta risultante sarà vuota e indicata da un codice di stato HTTP 204 No Content se la richiesta ha esito positivo. Il print=silent è supportato dalle richieste GET , PUT , POST e PATCH .

Scrittura dei valori del server

I valori del server possono essere scritti in una posizione utilizzando un valore segnaposto, che è un oggetto con una singola chiave ".sv" . Il valore per quella chiave è il tipo di valore del server che desideriamo impostare. Ad esempio, per impostare un timestamp quando viene creato un utente, potremmo fare quanto segue:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" è l'unico valore del server supportato ed è il tempo trascorso dall'epoca UNIX in millisecondi.

Miglioramento delle prestazioni di scrittura

Se stiamo scrivendo grandi quantità di dati nel database, possiamo utilizzare il parametro print=silent per migliorare le nostre prestazioni di scrittura e ridurre l'utilizzo della larghezza di banda. Nel normale comportamento di scrittura, il server risponde con i dati JSON che sono stati scritti. Quando si specifica print=silent , il server chiude immediatamente la connessione una volta ricevuti i dati, riducendo l'utilizzo della larghezza di banda.

Nei casi in cui stiamo facendo molte richieste al database, possiamo riutilizzare la connessione HTTPS inviando una richiesta Keep-Alive nell'intestazione HTTP.

Condizioni di errore

L'API REST restituirà codici di errore in queste circostanze:

Codici di stato HTTP
400 Richiesta errata

Una delle seguenti condizioni di errore:

  • Impossibile analizzare i dati PUT o POST .
  • Dati PUT o POST mancanti.
  • La richiesta tenta di PUT o POST di dati troppo grandi.
  • La chiamata API REST contiene nomi figlio non validi come parte del percorso.
  • Il percorso della chiamata dell'API REST è troppo lungo.
  • La richiesta contiene un valore del server non riconosciuto.
  • L'indice per la query non è definito nelle regole del database in tempo reale di Firebase .
  • La richiesta non supporta uno dei parametri di query specificati.
  • La richiesta combina i parametri della query con una richiesta GET superficiale.
401 Non autorizzato

Una delle seguenti condizioni di errore:

404 Non trovato Il database Firebase specificato non è stato trovato.
500 Errore interno del server Il server ha restituito un errore. Vedere il messaggio di errore per ulteriori dettagli.
503 Servizio non disponibile Il database Firebase Realtime specificato è temporaneamente non disponibile, il che significa che la richiesta non è stata tentata.

Protezione dei dati

Firebase ha un linguaggio di sicurezza che ci consente di definire quali utenti hanno accesso in lettura e scrittura a diversi nodi dei nostri dati. Puoi leggere di più in Regole del database in tempo reale .

Ora che abbiamo coperto il salvataggio dei dati, possiamo imparare come recuperare i nostri dati dal database Firebase tramite l'API REST nella sezione successiva.