Nous voulons réaliser une application dans laquelle des participants en réseau doivent répondre à un quizz. On souhaite faire la somme de leurs réponses ou votes. Le principe de fonctionnement naturel est d'utiliser des composants comme "get value" de Firebase, pour permettre d'accéder aux données de la question, et quand l'utilisateur a répondu ou voté, renvoyer la réponse à la base de données avec une commande Store value. La base de données elle même va ensuite informer les autres utilisateurs de cette mise à jour Pour que l'application mobile - de tous les participants, sachent avec le gestionnaire d'évènements firebase "datachanged" qu'une mise à jour est intervenue. Tous des utilisateurs sur le réseau vont savoir que les valeurs de vote ont changé. Alors essayons de voir ce qui peut se passer quand plusieurs utilisateurs font des mises à jour. Par exemple on va prendre un utilisateur en vert et un deuxième en rouge. Ils vont émettre des mises à jour à peu près simultanées : le vert puis le rouge ensuite, va plus vite mais ça n'a pas d'importance. Ce dont on se rend compte c'est que le vert a met à jour la base de données à partir d'un état qui précède la mise à jour du rouge. Donc en faisant sa mise à jour, il écrase la mise à jour faite par le rouge. Le vote du rouge a été perdu. Dasn ce cas c'est le vote du rouge qui écrasé, parce que la mise à jour du vert est arrivée légèrement après mais si le vote du rouge était arrivé légèrement après celui du vert, ce serait pareil, c'est votre du vert qui aurait été écrasé. La seule manière de ne pas perdre de l'information, c'est que les cycles de lecture et d'écriture soient successifs, et que la transaction rouge ne commence qu'après la fin de la transaction verte. Le taux de perte va dépendre du temps d'aller retour entre la base de données et les votants, Ici par exemple entre Paris et New-York, on a 165 millisecondes Donc si on a ce genre d'acteurs ou si on a des réseaux à faible bande passante, dès qu'on aura plus de 1 ou 2 votes par seconde, il y a de bonnes chances de perdre des votes. Donc ce n'est pas une solution satisfaisante, il faut en trouver une autre. Alors comment va t-on faire pour résoudre ce problème ? Eh bien on va faire une mise à jour en deux temps : On va d'abord stocker les votes dans un tag séparé, et on fera la somme esnsuite. On va utiliser pour ça un composant Firebase qui s'appelle "Append Value" "Append Value" ça veut dire "ajouter à la fin". On va prendre le premier vote, ensuite le deuxième qu'on va mettre après en "Append" et ensuite le troisième qu'on va rajouter, et ainsi de suite. A n'importe quel moment, on peut compiler le résultat en allant chercher tous les votes et en mettant à jour la base de données. Eh bien maintenant, passons à la réalisation. Nous devons donc réaliser quatre fonctions 1. la fonction qui va créer le tag ANSWERS, 2. la fonction qui va le détruire à la fin du vote 3. la fonction qui va mettre à jour le vote à partir du vote client. C'est celle qui figure avec la flèche noire 4. la fonction qui va aller lire les votes dans le tag ANSWERS et qui va mettre à jour la somme des votes par réponse, dans le tag de la question. Donc on a ces quatre fonctions à faire et on a ajouté un bouton pour démarrer le vote et l'arrêter, ce qui correspond à créer et à supprimer le tag ANSWERS. Voilà une présentation générale du résultat dans laquelle on voit la partie du haut qui existe déjà dans la version précédente de l'application et la partie du bas avec 3 blocs qui correspondent à des fonctions nouvelles. Regardons d'abord les événements de l'interface utilisateur: 1. à l'initialisation et à la sélection du vote il n'y a pratiquement aucun changement, uniquement des changements mineurs qui permettent de passer les strings en constantes de manière à pouvoir plus facilement changer de langue, 2. ensuite on a le bouton SUBMIT, Alors là on a un changement plus important, on a remplacé tout le cycle de mise à jour directe de la base de données qui est ici par l'appel à une fonction que nous allons voir tout à l'heure, qui s'appelle "Add my vote" : ajouter mon vote et qui va donc mettre à jour le tag ANSWERS. 3. Le gestionnaire d'événements qui est nouveau, c'est celui qui permet de démarrer et d'arrêter le vote. C'est un bouton qui - normalement - doit être disponible seulement pour l'administrateur du vote. Donc sa présence ici est temporaire. Ces trois fonctions nouvelles nous allons les regarder un peu plus tard. Passons maintenant à la gestion des événements liés à Firebase en commençant par le changement ou la mise à jour des données corespondant à l'évènement "Datachanged", Pour ce qui concerne le TAG "question", il n'y a pas de changement ! Par contre, lorsque le TAG ANSWERS a changé, c'est à dire où un vote a été ajouté, on rajoute l'appel à la fonction qui compte les votes et met à jour la base de données avec le résultat des votes dans le tag "questions". On en profite également pour afficher le nombre de votes sur le bouton SUBMIT. Aucun changement n'est nécessaire sur les autres événements liés à Firebase. On s'est limité dans notre cas, à ajouter des éléments qui permettent de traduire plus facilement l'application dans d'autres langues. ou de conserver des fonctions de debug. Décrivons maintenant les 4 fonctions nouvelles à commencer par les deux fonctions qui créent et qui détruisent le TAG ANSWERS et qui permettent de démarrer ou d'arrêter la procédure de vote. La fonction "startPoll" ou "démarrer le vote" vérifie d'abord que la question existe et si c'est le cas elle crée le tag ANSWERS en y incluant un premier vote nul avec une liste qui ne comprend que des 0. Ce premier vote "nul" peut être utile pour vérifier la validité des prochains votes, par exemple sur la structure ou la longueur de la liste. Ensuite la fonction "stop poll". Elle permet d'arrêter le vote et détruire le tag ANSWERS. après avoir effectué cette destruction, comme la fonction startPoll, elle demande une mise à jour la liste des TAGs pour que ce chnagement soit connu de l'application. Passons maintenant à la fonction "addMyVote" qui ajoute un vote à la liste dans le tag ANSWERS. Cette fonction commence par vérifier la présence de ce tag puis crée une liste de la même longueur que celle des réponses possibles. Dans cette liste elle met toutes les valeurs à 0 puis elle met à 1 l'index correspondant au vote de l'utilisateur. Ensuite elle envoie à Firebase une demande d'ajout "AppendValue" au tag ANSWERS. La dernière fonction c'est celle qui fait le compte des votes. Elle commence par créer une liste où toutes les valeurs sont à zéro, puis avec une boucle additionne tous les votes à cette première liste. Ensuite elle crée une copie du Tag "question", avec toutes ses données, puis remplace - dans cette copie - les valeurs correspondant au résultat du vote. Elle envoie ensuite une demande de mise à jour à Firebase avec "Store Value". Dans ces fonctions on a utilisé très peu de variables nouvelles, par contre on a remplacé la valeur des index par des constantes pour éviter de se tromper et pour permettre des modifications faciles de ces index l'index pour la question, pour la liste des réponses, pour le résulta du vote, etc. On a aussi remplacé les chaines de caractères par des constantes, ce qui nous permettra de convertir cette application en français, en espagnol etc. Voilà, Eh bien on a terminé le code, Il n'y a plus qu'à tester