Enregistrement des données

Économiser des données

PUT Écrire ou remplacer des données dans un chemin d'accès défini, comme fireblog/users/user1/<data>
PATCH Mettez à jour certaines des clés d'un chemin d'accès défini sans remplacer toutes les données.
POST Ajouter à une liste de données dans notre base de données Firebase Chaque fois que nous envoyons une requête POST, le client Firebase génère une clé unique, comme fireblog/users/<unique-id>/<data>.
SUPPRIMER Supprimez les données de la référence de base de données Firebase spécifiée.

Écrire des données avec PUT

L'opération d'écriture de base via l'API REST est PUT. Pour illustrer l'enregistrement des données, nous allons créer une application de blog avec des posts et des utilisateurs. Toutes les données de notre application seront stockées sous le chemin d'accès "fireblog", à l'URL de la base de données Firebase "https://docs-examples.firebaseio.com/fireblog".

Commençons par enregistrer des données utilisateur dans notre base de données Firebase. Nous stockons chaque utilisateur avec un nom d'utilisateur unique, ainsi que son nom complet et sa date de naissance. Étant donné que chaque utilisateur dispose d'un nom d'utilisateur unique, il est logique d'utiliser PUT ici au lieu de POST, car nous disposons déjà de la clé et n'avons pas besoin d'en créer une.

Avec PUT, nous pouvons écrire une chaîne, un nombre, une valeur booléenne, un tableau ou un objet JSON dans notre base de données Firebase. Dans ce cas, nous lui transmettrons un objet:

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

Lorsqu'un objet JSON est enregistré dans la base de données, les propriétés de l'objet sont automatiquement mappées sur des emplacements enfants de manière imbriquée. Si nous accédons au nœud nouvellement créé, la valeur "Alan Turing " s'affiche. Nous pouvons également enregistrer des données directement dans un emplacement enfant:

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'

Les deux exemples ci-dessus (écrire la valeur en même temps qu'un objet et l'écrire séparément dans des emplacements enfants) entraîneront l'enregistrement des mêmes données dans notre base de données Firebase:

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

Une requête réussie sera indiquée par un code d'état HTTP 200 OK, et la réponse contiendra les données que nous avons écrites dans la base de données. Le premier exemple ne déclenche qu'un seul événement sur les clients qui surveillent les données, tandis que le second en déclenche deux. Il est important de noter que si des données existaient déjà sur le chemin d'accès des utilisateurs, la première approche les écraserait, mais la deuxième méthode ne modifierait que la valeur de chaque nœud enfant distinct, tout en laissant les autres enfants inchangés. PUT équivaut à set() dans notre SDK JavaScript.

Mettre à jour des données avec PATCH

À l'aide d'une requête PATCH, nous pouvons mettre à jour des enfants spécifiques à un emplacement sans écraser les données existantes. Ajoutons le surnom de Turing à ses données utilisateur à l'aide d'une requête PATCH:

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

La requête ci-dessus écrit nickname dans notre objet alanisawesome sans supprimer les enfants name ou birthday. Notez que si nous avions émis une requête PUT ici, name et birthday auraient été supprimés, car ils n'étaient pas inclus dans la requête. Les données de notre base de données Firebase se présentent maintenant comme suit:

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

Une requête réussie est indiquée par un code d'état HTTP 200 OK, et la réponse contient les données mises à jour écrites dans la base de données.

Firebase est également compatible avec les mises à jour multicanaux. Cela signifie que PATCH peut désormais mettre à jour des valeurs à plusieurs endroits de votre base de données Firebase en même temps. Cette fonctionnalité puissante vous permet de dénormaliser vos données. Grâce aux mises à jour multicanaux, nous pouvons ajouter des surnoms à Alan et à Grace en même temps:

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

Après cette mise à jour, les surnoms d'Alan et de Grace ont été ajoutés:

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

Notez que le comportement sera différent si vous essayez de mettre à jour des objets en écrivant des objets avec les chemins inclus. Voyons ce qui se passe si nous essayons plutôt de mettre à jour Grace et Alan de cette manière:

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

Cela entraîne un comportement différent, à savoir l'écrasement de l'intégralité du nœud /fireblog/users:

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

Mettre à jour des données avec des requêtes conditionnelles

Vous pouvez utiliser des requêtes conditionnelles, l'équivalent REST des transactions, pour mettre à jour les données en fonction de leur état existant. Par exemple, si vous souhaitez augmenter un compteur de votes positifs et vous assurer que le nombre reflète précisément plusieurs votes positifs simultanés, utilisez une requête conditionnelle pour écrire la nouvelle valeur dans le compteur. Au lieu de deux écritures qui définissent le compteur sur le même nombre, l'une des requêtes d'écriture échoue et vous pouvez réessayer la requête avec la nouvelle valeur.
  1. Pour effectuer une requête conditionnelle à un emplacement, obtenez l'identifiant unique des données actuelles à cet emplacement ou l'ETag. Si les données changent à cet emplacement, l'ETag change également. Vous pouvez demander un ETag avec n'importe quelle méthode autre que PATCH. L'exemple suivant utilise une requête GET.
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    L'appel spécifique de l'ETag dans l'en-tête renvoie l'ETag de l'emplacement spécifié dans la réponse 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. Incluez l'ETag renvoyé dans votre prochaine requête PUT ou DELETE pour mettre à jour les données qui correspondent spécifiquement à cette valeur d'ETag. Pour suivre notre exemple, mettez à jour le compteur sur 11, soit une valeur supérieure de 1 à la valeur initiale de 10 extraite, et échouez la requête si la valeur ne correspond plus, en utilisant le code suivant:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    Si la valeur des données à l'emplacement spécifié est toujours 10, l'ETag de la requête PUT correspond et la requête aboutit, en écrivant 11 dans la base de données.
    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 l'emplacement ne correspond plus à l'ETag, ce qui peut se produire si un autre utilisateur a écrit une nouvelle valeur dans la base de données, la requête échoue sans écrire dans l'emplacement. La réponse de retour inclut la nouvelle valeur et l'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. Utilisez les nouvelles informations si vous décidez de réessayer la requête. Realtime Database ne relance pas automatiquement les requêtes conditionnelles ayant échoué. Toutefois, vous pouvez utiliser la nouvelle valeur et l'ETag pour créer une nouvelle requête conditionnelle avec les informations renvoyées par la réponse d'échec.

Les requêtes conditionnelles basées sur REST implémentent la norme HTTP if-match. Toutefois, ils diffèrent de la norme sur les points suivants:

  • Vous ne pouvez fournir qu'une seule valeur ETag pour chaque requête if-match, et non plusieurs.
  • Bien que la norme suggère que les ETags soient renvoyés avec toutes les requêtes, la base de données en temps réel ne renvoie des ETags que pour les requêtes incluant l'en-tête X-Firebase-ETag. Cela réduit les coûts de facturation pour les requêtes standards.

Les requêtes conditionnelles peuvent également être plus lentes que les requêtes REST standards.

Enregistrer des listes de données

Pour générer une clé unique basée sur un code temporel pour chaque enfant ajouté à une référence de base de données Firebase, nous pouvons envoyer une requête POST. Pour notre chemin d'accès users, il était logique de définir nos propres clés, car chaque utilisateur dispose d'un nom d'utilisateur unique. Toutefois, lorsque les utilisateurs ajoutent des articles de blog à l'application, nous utilisons une requête POST pour générer automatiquement une clé pour chaque article de blog:

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

Notre chemin d'accès posts contient désormais les données suivantes:

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

Notez que la clé -JSOpn9ZC54A4P4RoqVa a été générée automatiquement pour nous, car nous avons utilisé une requête POST. Une requête réussie est indiquée par un code d'état HTTP 200 OK, et la réponse contient la clé des nouvelles données ajoutées:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

Supprimer des données

Pour supprimer des données de la base de données, nous pouvons envoyer une requête DELETE avec l'URL du chemin d'accès à partir duquel nous souhaitons supprimer les données. La commande suivante supprimerait Alan de notre chemin users:

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

Une requête DELETE réussie est indiquée par un code d'état HTTP 200 OK avec une réponse contenant null JSON.

Paramètres d'URI

L'API REST accepte les paramètres URI suivants lors de l'écriture de données dans la base de données:

auth

Le paramètre de requête auth permet d'accéder aux données protégées par Firebase Realtime Database Security Rules et est compatible avec tous les types de requêtes. L'argument peut être notre secret d'application Firebase ou un jeton d'authentification, que nous verrons dans la section sur l'autorisation des utilisateurs. Dans l'exemple suivant, nous envoyons une requête POST avec un paramètre auth, où CREDENTIAL est notre secret d'application Firebase ou un jeton d'authentification:

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

imprimer

Le paramètre print nous permet de spécifier le format de notre réponse à partir de la base de données. Ajouter print=pretty à notre requête renvoie les données dans un format lisible. print=pretty est compatible avec les requêtes GET, PUT, POST, PATCH et DELETE.

Pour supprimer la sortie du serveur lors de l'écriture de données, nous pouvons ajouter print=silent à notre requête. La réponse obtenue sera vide et indiquée par un code d'état HTTP 204 No Content si la requête aboutit. print=silent est compatible avec les requêtes GET, PUT, POST et PATCH.

Écrire des valeurs de serveur

Les valeurs du serveur peuvent être écrites à un emplacement à l'aide d'une valeur d'espace réservé, qui est un objet avec une seule clé ".sv". La valeur de cette clé correspond au type de valeur de serveur que nous souhaitons définir. Par exemple, pour définir un code temporel lors de la création d'un utilisateur, procédez comme suit:

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

"timestamp" est la seule valeur de serveur acceptée. Il s'agit de l'heure écoulée depuis l'epoch UNIX, en millisecondes.

Améliorer les performances d'écriture

Si nous écrivons de grandes quantités de données dans la base de données, nous pouvons utiliser le paramètre print=silent pour améliorer nos performances d'écriture et réduire l'utilisation de la bande passante. Dans le comportement d'écriture normal, le serveur répond avec les données JSON écrites. Lorsque print=silent est spécifié, le serveur ferme immédiatement la connexion une fois les données reçues, ce qui réduit l'utilisation de la bande passante.

Lorsque nous envoyons de nombreuses requêtes à la base de données, nous pouvons réutiliser la connexion HTTPS en envoyant une requête Keep-Alive dans l'en-tête HTTP.

Conditions d'erreur

L'API REST renvoie des codes d'erreur dans les cas suivants:

Codes d'état HTTP
400 : requête incorrecte

L'une des conditions d'erreur suivantes:

  • Impossible d'analyser les données PUT ou POST.
  • Données PUT ou POST manquantes.
  • La requête tente de PUT ou de POST des données trop volumineuses.
  • L'appel d'API REST contient des noms d'enfants non valides dans le chemin d'accès.
  • Le chemin d'appel de l'API REST est trop long.
  • La requête contient une valeur de serveur non reconnue.
  • L'index de la requête n'est pas défini dans votre Firebase Realtime Database Security Rules.
  • La requête n'est pas compatible avec l'un des paramètres de requête spécifiés.
  • La requête mélange des paramètres de requête avec une requête GET peu profonde.
401 Non autorisé

L'une des conditions d'erreur suivantes:

  • Le jeton d'authentification a expiré.
  • Le jeton d'autorisation utilisé dans la requête n'est pas valide.
  • Échec de l'authentification avec un access_token.
  • La demande ne respecte pas votre Firebase Realtime Database Security Rules.
404 Introuvable La base de données Firebase spécifiée est introuvable.
500 Erreur interne du serveur Le serveur a renvoyé une erreur. Pour en savoir plus, consultez le message d'erreur.
503 Service indisponible La Firebase Realtime Database spécifiée est temporairement indisponible, ce qui signifie que la requête n'a pas été tentée.

Sécuriser les données

Firebase dispose d'un langage de sécurité qui nous permet de définir les utilisateurs disposant d'un accès en lecture et en écriture aux différents nœuds de nos données. Pour en savoir plus, consultez Realtime Database Security Rules.

Maintenant que nous avons vu comment enregistrer des données, nous allons apprendre à les récupérer dans la base de données Firebase via l'API REST dans la section suivante.