Como salvar dados |
|
---|---|
PUT | Grave ou substitua dados em um caminho definido, como fireblog/users/user1/<data> |
PATCH | Atualize algumas chaves de um caminho específico sem substituir todos os dados. |
POST | Adicione a uma lista de dados do banco de dados do Firebase. Sempre que uma solicitação POST é enviada, o cliente do Firebase gera uma chave exclusiva, como fireblog/users/<unique-id>/<data> |
DELETE | Remova os dados da referência especificada de banco de dados do Firebase. |
Gravar dados com PUT
A operação básica de gravação por meio da API REST é PUT
. Para
demonstrar a economia de dados, criaremos um aplicativo de blog com postagens e usuários. Todos os
dados do aplicativo serão armazenados no caminho do "fireblog", no URL do banco de dados do Firebase
"https://docs-examples.firebaseio.com/fireblog".
Vamos começar salvando alguns dados de usuário no banco de dados do Firebase. Armazenaremos cada usuário com base em um nome de usuário exclusivo, além do nome completo e data de nascimento. Como cada um terá um nome de usuário exclusivo, utilizaremos PUT
em vez de POST
, porque já temos a chave e não precisaremos criar outra.
O PUT
grava uma string, um número, um booleano, uma matriz ou qualquer objeto JSON no banco de dados do Firebase. Neste caso, transferiremos um objeto:
curl -X PUT -d '{ "alanisawesome": { "name": "Alan Turing", "birthday": "June 23, 1912" } }' 'https://docs-examples.firebaseio.com/fireblog/users.json'
Quando um objeto JSON é salvo no banco de dados, as propriedades dele são automaticamente mapeadas nos locais filhos, de maneira aninhada. Depois de navegar até o nó recém-criado, veremos o valor "Alan Turing". Também podemos salvar os dados diretamente em um local filho:
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'
Nos dois exemplos acima (gravar o valor e o objeto ao mesmo tempo e gravá-los separadamente nos locais filhos), os mesmos dados são salvos no banco de dados do Firebase:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing" } } }
Um código de status HTTP 200 OK
indica que uma solicitação foi bem-sucedida e que a resposta contém os dados gravados no banco de dados. O primeiro exemplo só aciona um evento nos clientes que estão monitorando os dados, enquanto o segundo aciona dois. É importante observar que a primeira abordagem substitui os dados existentes no caminho dos usuários. No entanto, o segundo método apenas modifica o valor de cada nó filho, deixando os demais filhos inalterados. O PUT
é equivalente a set()
no SDK para JavaScript.
Atualizar dados com PATCH
Uma solicitação PATCH
atualiza filhos específicos em um local sem substituir os dados já existentes. Vamos adicionar o apelido de Alan Turing aos dados de usuário com uma solicitação PATCH
:
curl -X PATCH -d '{ "nickname": "Alan The Machine" }' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
A solicitação acima gravará nickname
em nosso objeto alanisawesome
sem excluir os filhos name
ou birthday
. Se tivéssemos emitido uma solicitação PUT
aqui, name
e birthday
seriam excluídos porque não foram incluídos na solicitação. Os dados no nosso banco de dados do Firebase agora aparecem assim:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing", "nickname": "Alan The Machine" } } }
Um código de status HTTP 200 OK
indica que uma solicitação foi bem-sucedida e que a resposta contém os dados atualizados gravados no banco de dados.
O Firebase também faz atualizações em vários caminhos. Ou seja, agora o PATCH
pode atualizar valores em vários locais simultaneamente no banco de dados do Firebase. Esse é um recurso bastante eficiente para desnormalizar seus dados. Com as atualizações em vários caminhos, é possível adicionar apelidos a Alan e Grace simultaneamente:
curl -X PATCH -d '{ "alanisawesome/nickname": "Alan The Machine", "gracehopper/nickname": "Amazing Grace" }' \ 'https://docs-examples.firebaseio.com/fireblog/users.json'
Após essa atualização, os apelidos de Alan e Grace serão adicionados:
{ "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" } } }
Se fizer isso gravando os objetos com os caminhos incluídos, o comportamento será diferente. Vejamos o que acontece quando tentamos atualizar Grace e Alan desta forma:
curl -X PATCH -d '{ "alanisawesome": {"nickname": "Alan The Machine"}, "gracehopper": {"nickname": "Amazing Grace"} }' \ 'https://docs-examples.firebaseio.com/fireblog/users.json'
O resultado será um comportamento diferente, ou seja, todo o nó /fireblog/users
será substituído:
{ "users": { "alanisawesome": { "nickname": "Alan The Machine" }, "gracehop": { "nickname": "Amazing Grace" } } }
Como atualizar dados com solicitações condicionais
Você pode usar solicitações condicionais, que equivalem ao REST em transações, para atualizar dados de acordo com o estado existente. Por exemplo, se você quiser aumentar um contador de votos e verificar se a contagem reflete com precisão vários votos simultâneos, use uma solicitação condicional para gravar o novo valor no contador. Em vez de duas gravações que alteram o contador para o mesmo número, uma das solicitações de gravação é definida como falha. Então, você pode tentar uma nova solicitação com o novo valor.- Para executar uma solicitação condicional em um local, encontre o identificador exclusivo para os dados atuais nesse local, ou a ETag. Se os dados mudarem nesse local, a ETag também será alterada. É possível solicitar uma ETag com qualquer método diferente de
PATCH
. O exemplo a seguir usa uma solicitaçãoGET
.curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
Chamar especificamente a ETag no cabeçalho retorna a ETag do local especificado na resposta 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
- Inclua a ETag retornada na sua próxima solicitação
PUT
ouDELETE
para atualizar dados que correspondem especificamente ao valor ETag. Seguindo nosso exemplo, para atualizar o contador para 11, ou 1 maior que o valor inicial buscado de 10, e falhar a solicitação se o valor não corresponder mais, use o seguinte código:curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
Se o valor dos dados no local especificado ainda for 10, a ETag na solicitaçãoPUT
corresponderá e a solicitação será bem-sucedida, gravando 11 no banco de dados.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 o local não corresponder mais à ETag, o que pode ocorrer se outro usuário gravar um novo valor no banco de dados, a solicitação falhará sem gravar no local. A resposta de retorno inclui o novo valor e a 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
- Use as novas informações para repetir a solicitação. O Realtime Database não repete automaticamente as solicitações condicionais que falharam. No entanto, você pode usar o novo valor e a ETag para criar uma nova solicitação condicional com a informação retornada pela resposta de falha.
As solicitações condicionadas baseadas em REST implementam o padrão HTTP if-match. No entanto, eles diferem do padrão das seguintes maneiras:
- Você só pode fornecer um valor ETag para cada solicitação if-match.
- Embora o padrão sugira que as ETags sejam retornadas com todas as solicitações, o Realtime Database retorna apenas ETags com solicitações, incluindo o cabeçalho
X-Firebase-ETag
. Isso reduz os custos de cobrança para solicitações padrão.
Solicitações condicionais também podem ser mais lentas do que solicitações REST comuns.
Salvar listas de dados
Para gerar uma chave exclusiva baseada em carimbo de data/hora para cada filho adicionado a uma referência de banco de dados do Firebase, podemos enviar uma solicitação POST
. Para nosso caminho users
, faz sentido definir nossas próprias chaves, já que cada usuário tem um nome de usuário exclusivo. No entanto, quando os usuários adicionarem postagens de blog ao app, usaremos uma solicitação POST
para gerar automaticamente uma chave para cada postagem:
curl -X POST -d '{ "author": "alanisawesome", "title": "The Turing Machine" }' 'https://docs-examples.firebaseio.com/fireblog/posts.json'
Agora, o caminho posts
tem os seguintes dados:
{ "posts": { "-JSOpn9ZC54A4P4RoqVa": { "author": "alanisawesome", "title": "The Turing Machine" } } }
A chave -JSOpn9ZC54A4P4RoqVa
foi gerada automaticamente porque usamos uma solicitação POST
. Um código de status HTTP 200 OK
indica que a solicitação foi bem-sucedida e que a resposta contém a chave dos novos dados adicionados:
{"name":"-JSOpn9ZC54A4P4RoqVa"}
Remover dados
Para remover dados do banco de dados, envie uma solicitação DELETE
com o URL do caminho dos dados a serem excluídos. Alan seria excluído do nosso caminho users
da seguinte maneira:
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
Uma solicitação DELETE
bem-sucedida será indicada por um código de status HTTP 200 OK
com uma resposta contendo null
de JSON.
Parâmetros de URI
A REST API aceita os seguintes parâmetros de URI ao gravar dados no banco de dados:
auth
Com o parâmetro de solicitação auth
, é possível acessar os dados protegidos pelas
regras de segurança do Firebase Realtime Database. Além disso, ele é
compatível com todos os tipos de solicitação. O argumento pode ser a chave secreta do app do Firebase ou um
token de autenticação, que será abordado na seção sobre autorização
do usuário. No exemplo a seguir, enviamos uma solicitação POST
com um parâmetro auth
, em que CREDENTIAL
é a chave secreta do app do Firebase ou um token de autenticação:
curl -X POST -d '{"Authenticated POST request"}' \ 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
O parâmetro print
permite especificar o formato da nossa resposta do banco de dados. Adicionar print=pretty
à nossa solicitação retornará os dados em um formato legível. print=pretty
é compatível com as solicitações GET
, PUT
, POST
, PATCH
e DELETE
.
Para suprimir a saída do servidor ao gravar dados, podemos adicionar print=silent
à solicitação. A resposta resultante estará vazia e indicada por um código de status HTTP 204 No Content
se a solicitação for bem-sucedida.
O print=silent
é compatível com solicitações GET
, PUT
, POST
e PATCH
.
Gravar valores de servidor
Os valores do servidor podem ser gravados em um local usando um valor de marcador, que é um objeto com uma única chave ".sv"
. O valor dessa chave é o tipo de valor de servidor a ser definido.
Por exemplo, para definir um carimbo de data/hora na criação de um usuário, faça o seguinte:
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
é o único valor de servidor compatível e é o tempo desde a época do UNIX em milissegundos.
Como melhorar o desempenho de gravação
Para gravar grandes quantidades de dados no banco de dados, podemos usar o parâmetro print=silent
para melhorar nosso desempenho de gravação e diminuir o uso da largura de banda. Em condições normais de gravação, o servidor responde com os dados JSON gravados.
Quando print=silent
é especificado, o servidor fecha imediatamente a conexão assim que os dados são recebidos, reduzindo o uso da largura de banda.
Ao fazer muitas solicitações para o banco de dados, reutilize a conexão HTTPS e envie uma solicitação Keep-Alive
para o cabeçalho HTTP.
Condições de erro
A REST API retornará códigos de erro nestas circunstâncias:
Códigos de status HTTP | |
---|---|
400 Solicitação inválida |
Uma das seguintes condições de erro:
|
401 Não autorizado |
Uma das seguintes condições de erro:
|
404 Não encontrado | O banco de dados do Firebase especificado não foi encontrado. |
500 Erro interno do servidor | O servidor retornou um erro. Consulte a mensagem de erro para mais detalhes. |
503 Serviço não disponível | O Firebase Realtime Database especificado está temporariamente indisponível, o que significa que não houve tentativa de solicitação. |
Proteção de dados
O Firebase tem uma linguagem de segurança para definir quais usuários têm acesso de leitura e gravação aos diferentes nós dos dados. Confira mais informações em Regras de segurança do Realtime Database.
Agora você já sabe como salvar dados. Na próxima seção aprenderemos a recuperá-los do banco de dados do Firebase com a API REST.