Guardar datos

Formas de guardar datos

PONER Escriba o reemplace datos en una ruta definida , como fireblog/users/user1/<data>
PARCHE Actualice algunas de las claves para una ruta definida sin reemplazar todos los datos.
CORREO Agregar a una lista de datos en nuestra base de datos Firebase. Cada vez que enviamos una solicitud POST , el cliente de Firebase genera una clave única, como fireblog/users/<unique-id>/<data>
BORRAR Elimina datos de la referencia de la base de datos de Firebase especificada.

Escribir datos con PUT

La operación de escritura básica a través de la API REST es PUT . Para demostrar los datos de ahorro, crearemos una aplicación de blogs con publicaciones y usuarios. Todos los datos de nuestra aplicación se almacenarán en la ruta de `fireblog`, en la URL de la base de datos de Firebase `https://docs-examples.firebaseio.com/fireblog`.

Comencemos guardando algunos datos del usuario en nuestra base de datos de Firebase. Almacenaremos a cada usuario con un nombre de usuario único y también almacenaremos su nombre completo y fecha de nacimiento. Dado que cada usuario tendrá un nombre de usuario único, tiene sentido usar PUT aquí en lugar de POST ya que ya tenemos la clave y no necesitamos crear una.

Usando PUT , podemos escribir una cadena, un número, un valor booleano, una matriz o cualquier objeto JSON en nuestra base de datos de Firebase. En este caso le pasaremos un objeto:

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

Cuando se guarda un objeto JSON en la base de datos, las propiedades del objeto se asignan automáticamente a ubicaciones secundarias de forma anidada. Si navegamos hasta el nodo recién creado, veremos el valor "Alan Turing". También podemos guardar datos directamente en una ubicación infantil:

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'

Los dos ejemplos anteriores (escribir el valor al mismo tiempo que un objeto y escribirlos por separado en ubicaciones secundarias) darán como resultado que los mismos datos se guarden en nuestra base de datos de Firebase:

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

Una solicitud exitosa se indicará con un código de estado HTTP 200 OK y la respuesta contendrá los datos que escribimos en la base de datos. El primer ejemplo solo activará un evento en los clientes que estén observando los datos, mientras que el segundo ejemplo activará dos. Es importante tener en cuenta que si ya existían datos en la ruta del usuario, el primer enfoque los sobrescribiría, pero el segundo método solo modificaría el valor de cada nodo secundario por separado y dejaría a los demás nodos secundarios sin cambios. PUT es equivalente a set() en nuestro SDK de JavaScript.

Actualización de datos con PATCH

Usando una solicitud PATCH , podemos actualizar niños específicos en una ubicación sin sobrescribir los datos existentes. Agreguemos el apodo de Turing a sus datos de usuario con una solicitud PATCH :

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

La solicitud anterior escribirá nickname para nuestro objeto alanisawesome sin borrar el name ni birthday de los niños. Tenga en cuenta que si hubiéramos emitido una solicitud PUT aquí, name y birthday se habrían eliminado ya que no se incluyeron en la solicitud. Los datos en nuestra base de datos de Firebase ahora se ven así:

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

Una solicitud exitosa se indicará con un código de estado HTTP 200 OK y la respuesta contendrá los datos actualizados escritos en la base de datos.

Firebase también admite actualizaciones de múltiples rutas. Esto significa que PATCH ahora puede actualizar valores en múltiples ubicaciones en su base de datos de Firebase al mismo tiempo, una característica poderosa que le ayuda a desnormalizar sus datos . Usando actualizaciones de rutas múltiples, podemos agregar apodos tanto a Alan como a Grace al mismo tiempo:

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

Después de esta actualización, se agregaron sus apodos a Alan y Grace:

{
  "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"
    }
  }
}

Tenga en cuenta que intentar actualizar objetos escribiéndolos con las rutas incluidas dará como resultado un comportamiento diferente. Echemos un vistazo a lo que sucede si intentamos actualizar Grace y Alan de esta manera:

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

Esto da como resultado un comportamiento diferente, es decir, sobrescribir todo el nodo /fireblog/users :

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

Actualización de datos con solicitudes condicionales

Puede utilizar solicitudes condicionales, el equivalente REST a las transacciones, para actualizar los datos según su estado existente. Por ejemplo, si desea aumentar un contador de votos positivos y desea asegurarse de que el recuento refleje con precisión varios votos positivos simultáneos, utilice una solicitud condicional para escribir el nuevo valor en el contador. En lugar de dos escrituras que cambian el contador al mismo número, una de las solicitudes de escritura falla y luego puede volver a intentar la solicitud con el nuevo valor.
  1. Para realizar una solicitud condicional en una ubicación, obtenga el identificador único de los datos actuales en esa ubicación, o la ETag. Si los datos cambian en esa ubicación, la ETag también cambia. Puede solicitar una ETag con cualquier método que no sea PATCH . El siguiente ejemplo utiliza una solicitud GET .
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    Llamar específicamente a la ETag en el encabezado devuelve la ETag de la ubicación especificada en la respuesta 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. Incluya la ETag devuelta en su próxima solicitud PUT o DELETE para actualizar los datos que coincidan específicamente con ese valor de ETag. Siguiendo nuestro ejemplo, para actualizar el contador a 11, o 1 mayor que el valor inicial obtenido de 10, y fallar la solicitud si el valor ya no coincide, use el siguiente código:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    Si el valor de los datos en el valor especificado La ubicación sigue siendo 10, la ETag en la solicitud PUT coincide y la solicitud se realiza correctamente, escribiendo 11 en la base de datos.
    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
    
    Si la ubicación ya no coincide con la ETag, lo que podría ocurrir si otro usuario escribiera un nuevo valor en la base de datos, la solicitud falla sin escribir en la ubicación. La respuesta de devolución incluye el nuevo valor y 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. Utilice la nueva información si decide volver a intentar la solicitud. Realtime Database no reintenta automáticamente las solicitudes condicionales que fallaron. Sin embargo, puede utilizar el nuevo valor y ETag para crear una nueva solicitud condicional con la información devuelta por la respuesta fallida.

Las solicitudes condicionales basadas en REST implementan el estándar HTTP if-match . Sin embargo, se diferencian del estándar en los siguientes aspectos:

  • Solo puede proporcionar un valor de ETag para cada solicitud de coincidencia, no varios.
  • Si bien el estándar sugiere que se devuelvan ETags con todas las solicitudes, Realtime Database solo devuelve ETags con solicitudes que incluyen el encabezado X-Firebase-ETag . Esto reduce los costos de facturación para solicitudes estándar.

Las solicitudes condicionales también pueden ser más lentas que las solicitudes REST típicas.

Guardar listas de datos

Para generar una clave única basada en marca de tiempo para cada niño agregado a una referencia de base de datos de Firebase, podemos enviar una solicitud POST . Para la ruta de nuestros users , tenía sentido definir nuestras propias claves ya que cada usuario tiene un nombre de usuario único. Pero cuando los usuarios agregan publicaciones de blog a la aplicación, usaremos una solicitud POST para generar automáticamente una clave para cada publicación de blog:

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

Nuestra ruta posts ahora tiene los siguientes datos:

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

Observe que la clave -JSOpn9ZC54A4P4RoqVa se generó automáticamente porque utilizamos una solicitud POST . Una solicitud exitosa se indicará con un código de estado HTTP 200 OK y la respuesta contendrá la clave de los nuevos datos que se agregaron:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

Eliminación de datos

Para eliminar datos de la base de datos, podemos enviar una solicitud DELETE con la URL de la ruta de la que nos gustaría eliminar los datos. Lo siguiente eliminaría a Alan de la ruta de nuestros users :

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

Una solicitud DELETE exitosa se indicará mediante un código de estado HTTP 200 OK con una respuesta que contiene JSON null .

Parámetros de URI

La API REST acepta los siguientes parámetros de URI al escribir datos en la base de datos:

autenticación

El parámetro de solicitud auth permite el acceso a datos protegidos por las reglas de seguridad de Firebase Realtime Database y es compatible con todos los tipos de solicitudes. El argumento puede ser el secreto de nuestra aplicación Firebase o un token de autenticación, que cubriremos en la sección de autorización de usuario . En el siguiente ejemplo, enviamos una solicitud POST con un parámetro auth , donde CREDENTIAL es el secreto de nuestra aplicación Firebase o un token de autenticación:

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

imprimir

El parámetro print nos permite especificar el formato de nuestra respuesta de la base de datos. Agregar print=pretty a nuestra solicitud devolverá los datos en un formato legible por humanos. print=pretty es compatible con solicitudes GET , PUT , POST , PATCH y DELETE .

Para suprimir la salida del servidor al escribir datos, podemos agregar print=silent a nuestra solicitud. La respuesta resultante estará vacía y se indicará con un código de estado HTTP 204 No Content si la solicitud se realiza correctamente. print=silent es compatible con solicitudes GET , PUT , POST y PATCH .

Escribir valores del servidor

Los valores del servidor se pueden escribir en una ubicación utilizando un valor de marcador de posición, que es un objeto con una única clave ".sv" . El valor de esa clave es el tipo de valor del servidor que deseamos establecer. Por ejemplo, para establecer una marca de tiempo cuando se crea un usuario podríamos hacer lo siguiente:

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

"timestamp" es el único valor de servidor admitido y es el tiempo transcurrido desde la época de UNIX en milisegundos.

Mejorar el rendimiento de escritura

Si escribimos grandes cantidades de datos en la base de datos, podemos usar el parámetro print=silent para mejorar nuestro rendimiento de escritura y disminuir el uso de ancho de banda. En el comportamiento de escritura normal, el servidor responde con los datos JSON que se escribieron. Cuando se especifica print=silent , el servidor cierra inmediatamente la conexión una vez que se reciben los datos, lo que reduce el uso del ancho de banda.

En los casos en los que realizamos muchas solicitudes a la base de datos, podemos reutilizar la conexión HTTPS enviando una solicitud Keep-Alive en el encabezado HTTP.

Condiciones de error

La API REST devolverá códigos de error en estas circunstancias:

Códigos de estado HTTP
400 Petición Incorrecta

Una de las siguientes condiciones de error:

  • No se pueden analizar datos PUT o POST .
  • Faltan datos PUT o POST .
  • La solicitud intenta PUT o POST datos que son demasiado grandes.
  • La llamada a la API REST contiene nombres secundarios no válidos como parte de la ruta.
  • La ruta de llamada de la API REST es demasiado larga.
  • La solicitud contiene un valor de servidor no reconocido.
  • El índice de la consulta no está definido en las reglas de seguridad de la base de datos en tiempo real de Firebase .
  • La solicitud no admite uno de los parámetros de consulta especificados.
  • La solicitud combina parámetros de consulta con una solicitud GET superficial.
401 No autorizado

Una de las siguientes condiciones de error:

404 No encontrado No se encontró la base de datos de Firebase especificada.
Error interno de servidor 500 El servidor devolvió un error. Consulte el mensaje de error para obtener más detalles.
503 Servicio no Disponible La Firebase Realtime Database especificada no está disponible temporalmente, lo que significa que no se intentó realizar la solicitud.

Proteger los datos

Firebase tiene un lenguaje de seguridad que nos permite definir qué usuarios tienen acceso de lectura y escritura a diferentes nodos de nuestros datos. Puede leer más al respecto en Reglas de seguridad de bases de datos en tiempo real .

Ahora que hemos cubierto cómo guardar datos, podemos aprender cómo recuperar nuestros datos de la base de datos de Firebase a través de la API REST en la siguiente sección.