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

Scrivere dati con PUT

L'operazione di scrittura di base tramite l'API REST è PUT . Per dimostrare il salvataggio dei dati, creeremo un'applicazione di blog 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. Memorizzeremo 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 utilizzare PUT qui invece di POST poiché abbiamo già la chiave e non è necessario crearne una.

Usando PUT , possiamo scrivere una stringa, un numero, un valore 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 passiamo 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 in 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 andata a buon fine 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à 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 elementi secondari specifici in una posizione senza sovrascrivere i dati esistenti. Aggiungiamo il soprannome 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 oggetto alanisawesome senza eliminare il name o i bambini birthday . Si noti che se invece avessimo emesso una richiesta PUT qui, name e birthday sarebbero stati cancellati poiché non erano inclusi nella richiesta. I dati nel nostro database Firebase ora hanno questo aspetto:

{
  "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 può ora aggiornare contemporaneamente i valori in più posizioni nel database Firebase, una potente funzionalità che consente di denormalizzare i 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 ad Alan che a Grace sono stati aggiunti 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 nodo /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 si desidera aumentare un contatore di voti positivi e assicurarsi che il conteggio rifletta accuratamente più voti positivi simultanei, utilizzare 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 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 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. Includi l'ETag restituito nella tua 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 iniziale recuperato 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 al 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 ha scritto un nuovo valore nel database, la richiesta ha esito negativo 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 ritentare la richiesta. Realtime Database non ritenta 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 non riuscita.

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 più.
  • Sebbene lo standard suggerisca di restituire ETag con tutte le richieste, Realtime Database restituisce solo 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 di blog all'app, utilizzeremo una richiesta POST per generare automaticamente una chiave per ogni post di blog:

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

Il nostro percorso 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 andata a buon fine 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 nostro percorso 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 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, che tratteremo 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 permette di specificare il formato della nostra risposta dal database. L'aggiunta di 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 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 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 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 effettuando 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 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 in tempo reale di Firebase .
  • La richiesta non supporta uno dei parametri di query specificati.
  • La richiesta combina parametri di query con una richiesta GET poco profonda.
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 in tempo reale Firebase 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 ai diversi nodi dei nostri dati. Puoi saperne di più 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.