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>
ELIMINARE Rimuovi 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 risparmio dei dati, creeremo un'applicazione di blog con post e utenti. Tutti i dati per la nostra applicazione verranno archiviati nel percorso "fireblog", all'URL del database Firebase "https://docs-examples.firebaseio.com/fireblog".

Iniziamo salvando alcuni dati utente nel nostro database Firebase. Memorizzeremo ciascun 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 utilizzare qui PUT 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 automaticamente mappate alle posizioni secondarie in modo nidificato. Se navighiamo verso il nodo appena creato, vedremo il valore "Alan Turing". Possiamo anche salvare i dati direttamente in una posizione secondaria:

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, ovvero scrivere il valore contemporaneamente come oggetto e scriverlo separatamente nelle posizioni secondarie, comporteranno il salvataggio degli stessi dati nel nostro database Firebase:

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

Una richiesta riuscita verrà indicata da un codice di stato HTTP 200 OK e la risposta conterrà i dati che abbiamo scritto nel database. Il primo esempio attiverà solo un 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 dell'utente, 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à nickname al nostro alanisawesome oggetto Alanis senza cancellare il name o birthday dei bambini. Tieni presente che se invece avessimo emesso una richiesta PUT qui, name e birthday sarebbero stati eliminati poiché non erano inclusi nella richiesta. I dati nel nostro database Firebase ora appaiono così:

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

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

Firebase supporta anche aggiornamenti multipercorso. Ciò significa che PATCH ora può aggiornare contemporaneamente i valori in più posizioni nel database Firebase, 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"
    }
  }
}

Tieni presente che provare ad aggiornare gli oggetti scrivendo oggetti con i percorsi inclusi comporterà un comportamento diverso. Diamo un'occhiata a cosa succede se proviamo invece 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, ovvero la sovrascrittura dell'intero nodo /fireblog/users :

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

Aggiornamento dei dati con richieste condizionate

È 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 fallisce ed è quindi possibile ritentare 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 utilizza una richiesta GET .
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    La chiamata specifica all'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. Includi 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 seguente codice:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    Se il valore dei dati nel valore specificato location è 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 scrivesse un nuovo valore nel database, la richiesta fallisce senza scrivere nella posizione. La risposta restituita 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. Realtime Database non ritenta automaticamente le richieste condizionali non riuscite. Tuttavia, puoi utilizzare il nuovo valore e l'ETag per creare una nuova richiesta condizionale con le informazioni restituite dalla risposta fail.

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

  • Puoi fornire solo un valore ETag per ogni richiesta if-match, non multipli.
  • 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 percorso dei nostri posts ora ha i seguenti dati:

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

Tieni presente che la chiave -JSOpn9ZC54A4P4RoqVa è stata generata automaticamente per noi perché abbiamo utilizzato una richiesta POST . Una richiesta riuscita verrà 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 di richiesta auth consente l'accesso ai dati protetti dalle regole di sicurezza del database Firebase Realtime 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. Aggiungendo print=pretty alla nostra richiesta verranno restituiti i dati in un formato leggibile dall'uomo. print=pretty è supportato dalle richieste GET , PUT , POST , PATCH e DELETE .

Per sopprimere 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. 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 viene specificato 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 dati troppo grandi.
  • La chiamata API REST contiene nomi figlio non validi come parte del percorso.
  • Il percorso della chiamata API REST è troppo lungo.
  • La richiesta contiene un valore del server non riconosciuto.
  • L'indice per la query non è definito nelle regole di sicurezza del database Firebase Realtime .
  • La richiesta non supporta uno dei parametri di query specificati.
  • La richiesta combina i parametri di 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. Per ulteriori dettagli vedere il messaggio di errore.
503 servizio non disponibile Il Firebase Realtime Database specificato è temporaneamente non disponibile, il che significa che la richiesta non è stata tentata.

Protezione dei dati

Firebase dispone di un linguaggio di sicurezza che ci consente di definire quali utenti hanno accesso in lettura e scrittura ai diversi nodi dei nostri dati. Puoi leggere ulteriori informazioni a riguardo in Regole di sicurezza del database in tempo reale .

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