Salvar dados

Como salvar dados

PUT Grave ou substitua dados em um caminho definido, como messages/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 Firebase gera uma chave exclusiva, como messages/users//.
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 da REST API é PUT. Para demonstrar como salvar dados, criaremos um aplicativo de blog com postagens e usuários. Todos os dados do aplicativo serão armazenados no URL do banco de dados do Firebase: https://docs-examples.firebaseio.com/rest/saving-data/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. Nesse caso, passaremos um objeto para ele:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/rest/saving-data/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 node 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/rest/saving-data/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/rest/saving-data/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 node 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/rest/saving-data/users/alanisawesome.json'

A solicitação acima grava nickname no objeto alanisawesome sem excluir os filhos name ou birthday. Se, em vez disso, tivéssemos usado uma solicitação PUT, name e birthday teriam sido excluídos, já que não foram incluídos na solicitação. Agora os dados do Firebase estão 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 (em inglês). 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/rest/saving-data/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/rest/saving-data/users.json'

O resultado será um comportamento diferente, ou seja, todo o node /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.
  1. 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. Você pode solicitar uma ETag com qualquer método diferente de PATCH. O exemplo a seguir usa uma solicitação GET.
    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
    
  2. Inclua a ETag retornada na sua próxima solicitação PUT ou DELETE para atualizar dados que correspondem especificamente ao valor ETag. Seguindo nosso exemplo, para atualizar o contador para 11, ou 1 unidade a mais do que o valor inicial recuperado de 10, e definir a solicitação como falha 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, ele corresponderá à ETag na solicitação PUT. Assim, a solicitação terá sucesso e gravará o valor 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
    
  3. Use as novas informações se você quiser repetir a solicitação. O Realtime Database não repete automaticamente 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 retornem com todas as solicitações, o Realtime Database apenas retorna 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.

Como salvar listas de dados

Para gerar uma chave exclusiva baseada em timestamp para cada filho adicionado a uma referência de banco de dados do Firebase, envie uma solicitação POST. Definimos nossas próprias chaves no caminho users, já que cada usuário tem um nome 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/rest/saving-data/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 caminho users desta maneira:

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

Um código de status HTTP 200 OK com uma resposta contendo JSON null indica que a solicitação DELETE foi bem-sucedida.

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 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, uma solicitação POST é enviada com um parâmetro auth, onde 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/rest/saving-data/auth-example.json?auth=CREDENTIAL'

print

No parâmetro print, especifique o formato da resposta com base no banco de dados. A inclusão de print=pretty na solicitação retorna os dados em um formato legível. print=pretty pode ser usado nas solicitações GET, PUT, POST, PATCH e DELETE.

Para suprimir a saída do servidor ao gravar dados, podemos adicionar print=silent à solicitação. Se ela for bem-sucedida, a resposta resultante será vazia e indicada por um código de status HTTP 204 No Content. print=silent é compatível com solicitações GET, PUT, POST e PATCH.

Gravar valores de servidor

Grave valores de servidor em um local usando um valor de marcador, ou seja, 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 timestamp na criação de um usuário, faça o seguinte:

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

"timestamp" é o único valor de servidor permitido, representando o tempo em milissegundos desde o início da era UNIX.

Como melhorar o desempenho de gravação

Para gravar um grande volume de dados no banco de dados, use o parâmetro print=silent para melhorar o desempenho da gravação e reduzir 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 a conexão imediatamente após o recebimento dos dados e reduz o uso da largura de banda.

Quando são feitas 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:

  • Não é possível analisar dados do PUT ou do POST.
  • Os dados do PUT ou do POST estão ausentes.
  • A solicitação tenta executar PUT ou POST em dados muito extensos.
  • A chamada à REST API contém nomes de filhos inválidos como parte do caminho.
  • O caminho da chamada à REST API é muito longo.
  • A solicitação contém um valor de servidor não reconhecido.
  • O índice para a consulta não foi definido nas regras do Firebase Realtime Database.
  • A solicitação é incompatível com um dos parâmetros de consulta especificados.
  • A solicitação combina parâmetros de consulta com uma solicitação GET superficial.
401 Não autorizado

Uma das seguintes condições de erro:

  • O token de autenticação expirou.
  • O token de autenticação usado na solicitação é inválido.
  • Falha na autenticação com um access_token.
  • A solicitação viola as regras do Firebase Realtime Database
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 nodes dos dados. Leia mais sobre esse assunto em Como proteger seu app.

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.

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.