1. Introduction

Ce chapitre présente l’ensemble des technologies mises en œuvre dans le cadre du projet Hairbnb.

L’analyse portera sur les outils utilisés lors des différentes phases du projet : l’étude préliminaire, le développement de l’application, ainsi que la rédaction de la documentation et du présent rapport.

Les décisions technologiques seront examinées et justifiées, accompagnées d’une analyse comparative avec les alternatives disponibles sur le marché.

Cette présentation accordera une attention particulière aux technologies backend et frontend, qui constituent le cœur technique de l’application.

Ces éléments fondamentaux nécessitent un développement approfondi afin de préparer efficacement l’analyse détaillée qui suivra dans le prochain chapitre.

La structure de ce chapitre reflète l’importance relative de chaque technologie dans l’architecture globale du projet.

Certains outils bénéficieront d’une présentation plus détaillée en raison de leur rôle central dans le fonctionnement de l’application, tandis que d’autres, bien qu’essentiels, seront abordés de manière plus concise.

Cette approche permettra d’établir les bases techniques nécessaires à la compréhension des choix d’implémentation et des défis rencontrés lors du développement de Hairbnb.

Les choix technologiques et techniques adoptés pour le développement du projet Hairbnb résultent de mes propres recherches, de mon autoformation, de ma curiosité à explorer des technologies qui m’étaient encore inconnues, ainsi que de mes efforts personnels.

Je me suis toujours positionné dans la perspective d’un étudiant, encore sans expérience professionnelle concrète ni accès direct au marché du travail, ce qui limite naturellement ma vision des pratiques en entreprise.

Il est donc possible que certains lecteurs ne partagent pas tous mes choix, et je comprends parfaitement que leur regard, enrichi par l’expérience, puisse différer du mien ou même identifier d’autres solutions plus adaptées, plus efficaces ou plus économiques.

Cette démarche reste avant tout un exercice d’apprentissage et de construction progressive de compétences.

2. Choix des environnements de développement intégrés (IDE)

Au cours de ma formation, les environnements de développement Microsoft, en particulier Visual Studio, ont été largement privilégiés dans le cadre des travaux pratiques.

Parallèlement, le module consacré à la programmation orientée objet en java nous ont permis de nous initier à l’environnement Eclipse, un IDE très répandu dans le domaine du développement Java.

Toutefois, l’interface et l’ergonomie d’Eclipse ne correspondaient pas pleinement à mes attentes.

En quête d’une alternative plus adaptée à ma manière de travailler, j’ai testé NetBeans, mais malgré des fonctionnalités proches, cet IDE ne m’a pas apporté de réelle amélioration sur les aspects qui me posaient problème.

C’est dans ce contexte que j’ai découvert IntelliJ IDEA, développé par JetBrains, et j’ai immédiatement apprécié la clarté de son interface, la richesse de ses outils d’assistance au développement, ainsi que sa gestion efficace des projets impliquant plusieurs technologies.

Cette première expérience concluante m’a progressivement amené à explorer d’autres outils de la même suite. (Ceci n’est pas une publicité 😉)

La cohérence entre les différents environnements proposés par JetBrains, leur spécialisation par langage ou technologie, ainsi que leur stabilité, ont constitué des arguments déterminants dans mon choix d’utiliser exclusivement cette suite pour l’ensemble du développement du projet Hairbnb.

Ce choix s’est appuyé sur plusieurs critères techniques :

  • La qualité de l’assistance à la saisie,

  • La fiabilité des outils de débogage,

  • L’intégration native avec Git,

  • La simplicité de configuration d’environnements complexes.

Critères Eclipse NetBeans IntelliJ IDEA

Interface utilisateur

Assez complexe, peu intuitive

Plus simple, mais datée

Intuitive, moderne et fluide

Performance

Bonne, mais lente au démarrage

Moyenne, parfois instable

Excellente, fluide même sur projets lourds

Support multi-langages

Bon (Java, C++, PHP avec plugins)

Limité sans extensions

Très large (Java, Kotlin, Python, etc.)

Plugins et extensions

Très riche (via Marketplace)

Plus limité

Large écosystème via JetBrains plugins

Outils de débogage

Complets mais peu ergonomiques

Standards

Puissants et bien intégrés

Intégration Git

Possible avec plugins

Native

Native, très fluide et bien intégrée

Assistance au développement

Basique (complétion, refactorisation)

Moyenne

Avancée (suggestions intelligentes, refactoring)

Mise en route / configuration

Peut être complexe

Simple

Guidée et rapide

Communauté / documentation

Très large

Moyenne

Large et bien structurée

Version gratuite

Oui (Eclipse IDE)

Oui

Oui (version Community)

Version payante disponible

Non

Non

Oui (Ultimate avec plus de fonctionnalités)

Développé par

Eclipse Foundation

Oracle / Apache

JetBrains

Sources :
- https://www.jetbrains.com/idea/features/
- https://netbeans.apache.org/features/
- https://www.eclipse.org/
- Articles comparatifs : GeeksForGeeks, JetBrains Blog, DZone
- Tutorial youTube : https://www.youtube.com/watch?v=WZpwCim3OgY&ab_channel=Matej%28kangarko%29

2.1. Android Studio pour le front-end de l’application (Flutter)

Le développement du front-end de l’application Hairbnb a été réalisé en Flutter, un framework open-source développé par Google (cette technologie sera abordée plus tard).

Pour accompagner ce choix, l’environnement de développement utilisé a été Android Studio, une solution robuste et bien intégrée, qui s’est naturellement imposée dans le cadre de ce projet.

Android Studio est un IDE basé sur IntelliJ IDEA, développé par JetBrains, ce lien n’est pas anodin : c’est Google lui-même qui a choisi de s’appuyer sur la technologie JetBrains pour créer un environnement optimisé pour le développement Android.

Image A

Ce choix institutionnel a renforcé ma confiance dans l’écosystème JetBrains, déjà adopté pour d’autres aspects du projet.

Lancé en 2013, Android Studio est devenu l’environnement de référence pour le développement d’applications Android.

Il propose une intégration complète avec le SDK Android, des outils de débogage puissants, un émulateur intégré, et une gestion facilitée des dépendances via Gradle.

Son support natif de Flutter et Dart en fait aujourd’hui l’un des IDE les plus adaptés à ce type de développement, aux côtés de Visual Studio Code.

Dans le cadre du projet Hairbnb, Android Studio a joué un rôle central dans la création de l’interface utilisateur, la gestion des interactions avec l’utilisateur, et l’intégration des services Firebase (authentification, base de données temps réel pour le chat, etc.).

Son éditeur visuel, sa gestion des widgets Flutter, et ses outils de prévisualisation en temps réel ont permis un développement plus fluide et une meilleure maîtrise du rendu final de l’application sur différentes tailles d’écran.

2.2. PyCharm pour le back-end de l’application (Django)

Pour le développement du back-end de l’application Hairbnb, le choix s’est orienté vers Django, un framework Python réputé pour sa robustesse, sa structure claire et sa richesse fonctionnelle dans la conception d’applications web sécurisées et maintenables.

Afin de tirer pleinement parti de cette technologie, l’environnement de développement utilisé a été PyCharm, un IDE spécialement conçu pour Python, développé par la société JetBrains.

Ce choix s’inscrit dans la continuité de l’écosystème JetBrains, déjà utilisé pour le front-end, et s’est révélé particulièrement adapté aux exigences du développement Django.

PyCharm, lancé en 2010, est aujourd’hui largement reconnu comme l’un des meilleurs IDEs pour le développement Python, tant en milieu académique que professionnel [1].

Il offre :

  • Une assistance au code intelligente (autocomplétion, navigation entre les fichiers, refactorisation).

  • Une intégration poussée avec les environnements virtuels Python (venv, pipenv, conda).

  • Un support natif des frameworks web tels que Django et Flask.

  • Des outils puissants de débogage, d’analyse de code et de test.

  • Une compatibilité directe avec les systèmes de gestion de version comme Git.

L’un des principaux avantages de PyCharm est sa prise en charge native et approfondie de `Django`[2].

Cette prise en charge se traduit par :

  • Une structure de projet prédéfinie et reconnue automatiquement.

  • Une compréhension intégrée des modèles (models.py), vues (views.py) et templates HTML.

  • Des outils spécifiques pour la gestion des migrations, des bases de données et du routage (fichiers urls.py).

  • Un terminal intégré permettant de gérer manage.py directement depuis l’IDE.

Dans le cadre du projet Hairbnb, ces fonctionnalités ont permis de :

  • Structurer rapidement le projet backend avec une architecture claire et modulaire.

  • Développer les API REST nécessaires à la communication avec le front-end Flutter.

  • Gérer la base de données PostgreSQL de manière fluide.

  • Assurer une cohérence technique avec les autres outils JetBrains (Android Studio pour le front-end).

  • Garantir la stabilité du code grâce aux outils de test et de débogage intégrés.

2.3. PhpStorm et le plugin AsciiDoc

Au moment où je rédige ces lignes et ce rapport, je travaille à l’aide d’un autre IDE de la suite JetBrains : PhpStorm.

Bien que cet environnement soit à l’origine destiné au développement PHP, je ne l’utilise pas pour ce langage.

Mon usage principal concerne l’édition de fichiers AsciiDoc, grâce au plugin dédié, que je trouve particulièrement pratique, moderne, intuitif et adapté à une rédaction structurée et professionnelle.

PhpStorm est un IDE développé par JetBrains, principalement conçu pour le développement en PHP et les technologies web (HTML, CSS, JavaScript, etc.).

Il bénéficie des mêmes standards de qualité que les autres produits de la suite JetBrains, notamment en matière d’interface, d’assistance intelligente au code et de gestion de projet[3].

Grâce à son système de plugins, PhpStorm peut être utilisé bien au-delà de sa spécialité initiale.

Dans le cadre de ce projet, j’ai installé et utilisé le plugin AsciiDoc [4] pour rédiger l’intégralité du rapport technique.

Ce plugin permet notamment :

  • Un aperçu en temps réel du rendu AsciiDoc,

  • Une coloration syntaxique adaptée,

  • La prise en charge des blocs structurés (titres, tableaux, citations, etc.),

  • Une intégration fluide avec le contrôle de version (Git).

Ce choix m’a permis de rédiger un rapport propre, structuré, tout en restant dans un environnement de développement familier et cohérent avec les autres outils utilisés pour le projet Hairbnb.

3. Pourquoi avoir choisi AsciiDoc pour ce rapport ?

Le choix d’AsciiDoc comme langage de rédaction pour ce rapport s’est imposé pour plusieurs raisons pratiques et techniques.

Contrairement à un traitement de texte classique (comme MS Word ou LibreOffice), AsciiDoc permet :

  • Une structuration claire du contenu grâce à une syntaxe légère et lisible.

  • Un contrôle précis de la mise en forme sans dépendre d’un logiciel graphique.

  • Une compatibilité avec le versionnage Git, ce qui facilite les sauvegardes, l’historique et la collaboration.

  • Une génération automatisée de documents PDF ou HTML avec un rendu professionnel.

  • Une intégration naturelle dans les outils de développement, en particulier avec les IDE JetBrains.

En optant pour AsciiDoc, l’objectif était de maintenir une cohérence entre les outils de développement et de documentation, tout en assurant une qualité de présentation professionnelle pour le livrable final du projet Hairbnb.

Je tiens à remercier mon collègue Corentin Chiodo, qui m’a fait découvrir cet outil.

Depuis, il est devenu pour moi incontournable dans la rédaction de rapports. Honnêtement, je me demande comment je faisais auparavant avec Word…​ (Ceci n’est pas une mauvaise publicité 😄)

4. Firebase

4.1. Présentation de Firebase

Firebase est une plateforme de développement d’applications mobiles et web proposée par Google.

Elle fournit un ensemble de services cloud permettant aux développeurs de concevoir, de tester et de déployer des applications plus rapidement, sans avoir à gérer une infrastructure serveur complexe[5].

Lancé initialement en 2011 comme un service de synchronisation de données en temps réel, Firebase a été racheté par Google en 2014, puis intégré dans son écosystème de services pour développeurs.

Depuis, il a connu une forte évolution, avec l’ajout de nombreuses fonctionnalités destinées à faciliter le cycle de vie complet d’une application.

Firebase se distingue par son approche Backend-as-a-Service (BaaS), en proposant des outils prêts à l’emploi pour :

  • L’authentification des utilisateurs (Firebase Authentication),

  • Le stockage de données en temps réel (Firebase Realtime Database) ou structuré (Cloud Firestore),

  • L’hébergement de fichiers et d’applications web (Firebase Hosting),

  • L’envoi de notifications (Firebase Cloud Messaging),

  • L’analyse d’utilisation (Firebase Analytics),

  • La gestion de fonctions serverless (Cloud Functions),

  • la supervision de performances et de crashs (Performance Monitoring, Crashlytics).

Dans le cadre du projet Hairbnb, Firebase a été principalement utilisé pour deux fonctionnalités essentielles :

  • La gestion de l’authentification des utilisateurs, en lien avec l’application Flutter côté front-end et le backend Django pour la vérification des identités.

  • La mise en place d’un système de messagerie instantanée entre les utilisateurs et les coiffeuses, grâce à l’intégration de Cloud Firestore, une base de données NoSQL temps réel proposée par Firebase.

4.2. Pourquoi choisir Firebase Authentication plutôt que Django Auth ?

Bien que Django propose son propre système d’authentification robuste (django.contrib.auth), plusieurs raisons ont motivé le choix de Firebase Authentication dans le cadre de ce projet mobile :

  • Meilleure intégration mobile : Firebase Auth fournit des SDKs natifs pour Flutter, Android et iOS, ce qui facilite l’intégration directe dans l’application mobile sans avoir à développer une API intermédiaire complexe côté Django.

  • Gestion des sessions côté client : la gestion de l’authentification est assurée côté client avec des tokens JWT sécurisés, ce qui réduit la charge du serveur et simplifie l’architecture.

  • Multi-fournisseurs d’identification : Firebase Auth permet facilement l’authentification via e-mail/mot de passe, Google, Facebook, etc., avec une interface de gestion intégrée.

  • Sécurité assurée par Google :

    • Les mots de passe ne sont pas stockés ni gérés manuellement sur le backend.

    • Firebase applique directement les meilleures pratiques en matière de sécurité (chiffrement, validation d’email, protection contre les attaques par force brute).

  • Gain de temps pour un petit projet : la mise en place de Firebase Auth est rapide et évite de devoir concevoir une logique d’inscription, de validation, de récupération de mot de passe, etc.

Dans ce contexte, Firebase Authentication s’est révélé plus adapté à une application mobile Flutter, tandis que Django Auth aurait nécessité davantage de développement et d’adaptations.

4.3. Pourquoi utiliser Firestore pour la messagerie plutôt qu’une solution PostgreSQL ?

Concernant la messagerie instantanée de l’application Hairbnb, le choix de Cloud Firestore s’explique également par des critères techniques liés à la nature temps réel du service attendu :

  • Synchronisation en temps réel : Firestore permet aux clients de s’abonner aux changements de données.
    Ainsi, lorsqu’un utilisateur envoie un message, celui-ci est reçu instantanément par l’autre utilisateur sans actualisation manuelle.

  • Pas besoin de WebSocket côté serveur : une solution PostgreSQL aurait nécessité la mise en place de WebSocket, d’un service de notification, ou d’un système intermédiaire (ex. Redis + channels), ce qui alourdit l’architecture et la charge serveur.

  • Indépendance du backend : les messages sont stockés et synchronisés directement entre l’application et Firestore.

Le backend Django peut y accéder si nécessaire, mais n’intervient pas dans le flux principal, ce qui réduit la latence et la charge serveur.

  • Scalabilité automatique : Firestore gère automatiquement le volume de données et la montée en charge, ce qui est intéressant dans une perspective d’évolution ou de croissance du projet.

  • Modèle NoSQL flexible : le stockage des conversations dans une structure document-collection permet une modélisation plus souple, adaptée à des échanges utilisateur ↔ utilisateur avec métadonnées.

Pour toutes ces raisons, Firestore s’est imposé comme une solution pragmatique, légère et parfaitement adaptée à la fonctionnalité de messagerie instantanée dans un environnement mobile.

4.4. Mise en œuvre dans Hairbnb

L’authentification des utilisateurs dans le projet Hairbnb repose sur la plateforme Firebase.

Plusieurs options ont été envisagées, testées, puis ajustées au fil du développement selon les contraintes techniques et les limites d’accès aux services.

4.4.1. Choix du mode d’authentification

Au départ, le projet prévoyait la prise en charge de trois modes d’authentification :

  • Par email et mot de passe,

  • Via Google Sign-In,

  • Via Facebook Login.

Cependant, en cours d’implémentation, certaines contraintes ont amené à ajuster ces choix :

  • L’authentification Facebook a été abandonnée, en raison d’une configuration complexe et chronophage, nécessitant notamment la validation de l’application via la console Meta Developers et une gestion stricte des politiques de confidentialité.

  • L’authentification par code envoyé par SMS (Phone Auth) a également été écartée, car elle requiert une inscription payante pour dépasser les quotas de test gratuits (limités à certains numéros).

Cette contrainte budgétaire ne correspondait pas aux objectifs d’un projet académique.

Les deux modes finalement retenus sont :

  • Email/mot de passe : simple à mettre en œuvre, fiable, et facilement contrôlable.

  • Google Sign-In : pratique pour les utilisateurs disposant d’un compte Google, avec une intégration fluide dans Flutter via Firebase.

Intégration dans le front-end (Flutter)

L’application mobile Flutter utilise le package officiel firebase_auth, combiné avec google_sign_in pour gérer l’authentification.

Principales étapes :

  • Formulaires personnalisés :

    • Inscription : email, mot de passe (avec validation locale et affichage des erreurs).

    • Connexion : même structure, avec feedback clair pour les erreurs de saisie ou d’identifiants.

Ecran de connexion Ecran d’inscription
Image A
Image B
  • Méthodes Firebase utilisées :

    • createUserWithEmailAndPassword() pour l’enregistrement,

    • signInWithEmailAndPassword() pour la connexion,

    • signInWithGoogle() pour la connexion via un compte Google (via le package google_sign_in),

    • signOut() pour la déconnexion,

  • Suivi de session utilisateur :

    • Grâce à authStateChanges(), l’interface s’adapte automatiquement selon que l’utilisateur est connecté ou non (navigation conditionnelle, redirection, affichage de l’avatar, etc.).

Les méthodes citées ci-dessus proviennent directement de la documentation officielle de Firebase Authentication[6].

Elles ont été intégrées telles quelles dans l’application Hairbnb, avec une compréhension fonctionnelle basée sur leur nom et leur comportement observé.

L’implémentation détaillée interne de ces méthodes relève des mécanismes propres au SDK Firebase, qui sont largement documentés, mais restent abstraits pour l’utilisateur final.

4.4.2. Intégration dans le back-end (Django)

Même si Firebase gère l’authentification, le backend Django sécurise les échanges API et vérifie l’identité de l’utilisateur à chaque requête.

Mécanisme mis en place :

  • Transmission d’un token d’identification :

    • Lorsqu’un utilisateur est connecté via Firebase, un ID token est généré.

    • Ce token est envoyé par l’application mobile dans l’en-tête HTTP des appels API (Authorization: Bearer <token>).

  • Vérification côté Django :

    • Le backend utilise le Firebase Admin SDK pour décoder et valider ce token via la méthode verify_id_token().

    • Si le token est valide, l’utilisateur est reconnu (email ou UID Firebase).

  • Lien avec la base PostgreSQL :

    • Les données Firebase (email, UID) sont utilisées pour lier l’utilisateur à un enregistrement local.

    • Si besoin, un nouvel utilisateur est créé automatiquement dans la base PostgreSQL, avec synchronisation des données essentielles (nom, email, rôle…).

Cette architecture garantit à la fois la simplicité côté client, la sécurité des échanges, et la cohérence des données côté serveur.

4.4.3. Qu’est-ce qu’un token ?

Un token (ou jeton, en français) est une chaîne de caractères générée automatiquement par un serveur d’authentification (comme Firebase) pour représenter l’identité d’un utilisateur de manière temporaire et sécurisée.

Dans le contexte de l’application Hairbnb, le token joue un rôle central dans la communication entre l’application mobile (front-end) et le serveur Django (back-end), en permettant à ce dernier de vérifier que la requête provient bien d’un utilisateur authentifié.

Caractéristiques d’un token

Un token possède généralement les caractéristiques suivantes :

  • Il est unique, associé à un utilisateur donné.

  • Il a une durée de vie limitée (ex. : 1 heure).

  • Il peut contenir des informations encodées : UID de l’utilisateur, adresse email, heure de création, etc.

  • Il est signé cryptographiquement pour garantir son intégrité et empêcher toute falsification. '''

4.4.4. Qu’est-ce que le SDK Firebase ?

Un SDK (Software Development Kit) est un ensemble d’outils, de bibliothèques, de documents et d’exemples de code fournis par un éditeur pour permettre aux développeurs d’interagir facilement avec une plateforme ou un service.

Le SDK Firebase désigne donc l’ensemble des bibliothèques mises à disposition par Google pour intégrer les services Firebase (authentification, base de données, stockage, messagerie, etc.) dans une application mobile ou web.[7]

Composants principaux du SDK Firebase

Selon la plateforme utilisée, différents SDK sont proposés :[8]

  • SDK Firebase pour Flutter : permet d’accéder aux services Firebase directement depuis une application Flutter.
    Il inclut des packages comme firebase_auth, cloud_firestore, firebase_messaging, firebase_core, etc.[9]

  • SDK Firebase Admin : destiné aux serveurs et backends, ce SDK permet de gérer les utilisateurs, de vérifier les jetons (ID token), d’envoyer des notifications, et d’interagir avec les services Firebase depuis un environnement sécurisé comme Django, Node.js ou Java[10].

  • SDK Firebase Web et natifs (iOS/Android) : disponibles pour les développeurs qui travaillent en JavaScript, Kotlin/Java ou Swift.

Rôle dans le projet Hairbnb

Deux SDK principaux ont été utilisés dans le cadre de ce projet :

  • Le SDK Flutter : utilisé côté client pour l’inscription, la connexion, la déconnexion, l’observation de l’état de session, et l’accès à Firestore pour la messagerie.

  • Le SDK Admin (Python) : utilisé côté serveur Django pour valider les ID tokens transmis par l’application Flutter et sécuriser les appels aux API.

L’utilisation conjointe de ces SDK a permis d’assurer une communication fluide et sécurisée entre l’application mobile, Firebase et le backend.

4.5. Firebase Authentication

Le système d’authentification de l’application Hairbnb repose sur une architecture distribuée, articulée autour de trois composants principaux :

  • Le front-end Flutter : responsable de l’interface utilisateur et de la gestion des formulaires d’inscription et de connexion.
    Il interagit directement avec Firebase via le SDK firebase_auth.

  • La plateforme Firebase : prend en charge l’authentification des utilisateurs, génère des jetons sécurisés (ID tokens), et permet la connexion via email/mot de passe ou Google.

  • Le back-end Django : reçoit les requêtes API accompagnées des jetons, les vérifie via le SDK Firebase Admin, et autorise ou refuse l’accès aux ressources en fonction de la validité du token et de l’identité de l’utilisateur.

Cette répartition des rôles permet de garantir à la fois :

  • Une authentification simple et rapide côté client,

  • Un contrôle d’accès sécurisé côté serveur,

  • Une bonne séparation des responsabilités techniques.

4.5.1. Schéma de l’authentification

Diagram
Figure 1. Schéma de l’authentification

4.5.2. Processus de connexion

  1. L’utilisateur saisit ses identifiants dans l’application (Flutter).

  2. L’application envoie la demande d’authentification à Firebase via firebase_auth.

  3. En cas de succès, Firebase renvoie un ID token (JWT).

  4. Ce token est ensuite inclus dans les appels API envoyés au serveur Django.

  5. Django utilise le Firebase Admin SDK pour vérifier la validité du token.

  6. Si le token est valide, l’accès aux ressources est autorisé, sinon, la requête est rejetée.

4.5.3. Processus de déconnexion

  1. L’utilisateur clique sur "Se déconnecter".

  2. Flutter appelle la méthode signOut() de firebase_auth.

  3. L’état d’authentification change, l’application redirige vers l’écran de connexion.

  4. Le token n’est plus envoyé dans les requêtes, donc Django considère l’utilisateur comme non authentifié.

4.5.4. Gestion des erreurs et sécurité

  • En cas d’identifiants incorrects, Firebase retourne un message d’erreur (ex. : mauvais mot de passe, compte inexistant).

  • En cas de token expiré ou falsifié, Django renvoie une erreur 401 (unauthorized).

  • Aucune donnée sensible n’est stockée localement sans protection.

  • Firebase applique automatiquement plusieurs mesures de sécurité : chiffrement, contrôle de session, limitation des tentatives, etc.

Cette architecture répartie permet de tirer profit de la sécurité native de Firebase tout en gardant un contrôle complet sur la logique métier côté serveur Django.

4.5.5. Avantages et limites rencontrés

L’intégration de Firebase Authentication dans le projet Hairbnb a offert de nombreux bénéfices, mais aussi présenté certaines contraintes, notamment liées à la spécificité de l’environnement Flutter / Django.

Points forts
  • Rapidité de mise en œuvre : l’intégration via les packages officiels (firebase_auth, google_sign_in) est rapide, bien documentée et stable.

  • Expérience utilisateur fluide : l’authentification est instantanée, sans rechargement d’écran ou délai perceptible, ce qui améliore le confort d’utilisation.

  • Documentation abondante : Firebase fournit une documentation complète, des guides d’implémentation et des tutoriels adaptés aux différents frameworks.

  • Sécurité gérée par Google : gestion des sessions, tokens, validation des utilisateurs, protection contre les attaques sont prises en charge par Firebase.

  • Évolutivité : possibilité d’ajouter facilement d’autres méthodes d’authentification (ex. : téléphone, réseaux sociaux) si nécessaire.

Limites et difficultés rencontrées
  • Validation côté serveur : bien que Firebase simplifie la partie front-end, la vérification des tokens côté Django nécessite une bonne compréhension de la logique des ID tokens et l’intégration du SDK Firebase Admin.

  • Écosystèmes séparés : Flutter (client), Firebase (authentification), et Django (serveur) reposent sur des environnements différents, ce qui rend la coordination plus délicate, notamment lors du débogage.

  • Quota et limitations : certains services Firebase (comme Phone Auth) sont limités dans l’offre gratuite, ce qui peut être contraignant pour un projet académique ou personnel.

  • Complexité potentielle pour Facebook Login : l’abandon de cette méthode est dû à la lourdeur des exigences de Meta (vérification, politique de confidentialité, configuration de l’application, etc.).

4.6. FireStore pour la messagerie instantanée

Dans le projet Hairbnb, un système de messagerie instantanée a été mis en place pour permettre aux clients et aux coiffeuses d’échanger directement au sein de l’application.

Cette fonctionnalité repose sur Cloud Firestore, l’une des bases de données proposées par Firebase.

4.6.1. Présentation de Firestore

Cloud Firestore est une base de données NoSQL cloud, proposée par Google Firebase, permettant le stockage de données structurées sous forme de documents dans des collections, avec une synchronisation en temps réel entre les clients[11].

Contrairement aux bases de données relationnelles comme PostgreSQL, Firestore n’utilise pas de schéma rigide, cela veut dire que chaque document peut contenir des champs différents, ce qui offre une grande flexibilité dans la gestion des données utilisateur, des messages, ou des métadonnées.

4.6.2. Avantages de Firestore pour un système de chat

Le choix de Firestore pour la messagerie dans Hairbnb repose sur plusieurs critères techniques :

  • Synchronisation en temps réel : les nouveaux messages sont automatiquement affichés sur l’interface des deux utilisateurs (client et coiffeuse) sans actualisation manuelle.

  • Événementiel intégré : Firestore notifie automatiquement l’application en cas d’ajout, de modification ou de suppression d’un message.

  • Modèle orienté document : adapté à la structure souple des conversations, avec un document par message, ou une collection par conversation.

  • Scalabilité automatique : le service gère la montée en charge sans configuration supplémentaire.

  • Pas besoin de gérer les sockets côté serveur : contrairement à une solution basée sur PostgreSQL, qui aurait nécessité un système WebSocket ou des queues de messages,
    Firestore prend en charge toute la logique temps réel côté client. [12]

4.6.3. Implémentation dans Hairbnb

L’organisation des données Firestore a été pensée pour être simple et efficace :

  • Chaque conversation est enregistrée dans une collection (par exemple conversations pour Hairbnb), identifiée par l’UID des deux participants.

  • Chaque message est un document dans une sous-collection messages/, contenant :

    • Le texte du message,

    • L’expéditeur (UID),

    • L’horodatage,

    • L’état de lecture.

Côté Flutter, le package cloud_firestore est utilisé pour :

  • Envoyer un message (add() dans la collection),

  • Afficher les messages en temps réel (snapshots() avec StreamBuilder),

  • Trier les messages par date (orderBy("timestamp")).

La messagerie est entièrement pilotée côté client, sans intervention directe du serveur Django dans le flux des messages, ce qui réduit la latence et la complexité backend.

Lors de l’implémentation de la messagerie, j’ai rencontré un problème de désynchronisation des messages, certaines réponses de la coiffeuse s’affichaient avant les messages du client, ou dans un ordre incohérent.

Cela se produisait notamment sur mobile, alors que tout fonctionnait correctement dans le navigateur.

Après plusieurs recherches, j’ai compris que le problème venait de la gestion des horodatages, et plus précisément d’un décalage entre les fuseaux horaires utilisés par les différents composants (Firebase, l’appareil mobile, serveur backend).

Pour que l’ordre des messages soit correct, il est essentiel que :

  • L’horloge de l’appareil mobile ou du navigateur (client Flutter),

  • Le backend Django,

  • Et Firebase

Soient tous synchronisés sur une même référence UTC.

Le fait que le navigateur était à l’heure alors que le téléphone ne l’était pas suffisait à perturber l’ordre d’affichage.

C’est un point de vigilance important à prendre en compte lorsqu’on utilise Firestore pour gérer une messagerie en temps réel.

4.7. Conclusion a-propos de Firebase

L’utilisation de la plateforme Firebase dans le projet Hairbnb s’est révélée particulièrement adaptée aux besoins d’une application mobile légère, fluide et centrée sur l’expérience utilisateur.

D’une part, Firebase Authentication a permis de mettre en place un système d’authentification sécurisé et flexible, compatible avec Flutter, sans devoir développer une solution maison côté serveur.

Son intégration rapide, sa gestion native des sessions, et la possibilité d’utiliser plusieurs modes de connexion (email/mot de passe, Google Sign-In) ont constitué des atouts majeurs.

Malgré l’abandon de certaines options initialement envisagées (comme Facebook Login ou Phone Auth), les objectifs fonctionnels ont été atteints avec efficacité.

D’autre part, Cloud Firestore s’est imposé comme une solution idéale pour la messagerie instantanée entre clients et coiffeuses.

Sa synchronisation en temps réel, son modèle orienté documents, et sa compatibilité naturelle avec Flutter ont permis de créer un module de communication simple, réactif, et sans complexité serveur inutile.

5. Les API de géolocalisation

La géolocalisation est une composante essentielle de l’application Hairbnb, notamment pour permettre aux coiffeuses d’enregistrer leur position, et aux clients de localiser les salons à proximité.

5.1. Définition et principe

La géolocalisation désigne le processus qui permet de déterminer la position géographique d’un appareil (ordinateur, smartphone, tablette) via des coordonnées GPS (latitude et longitude).

Cette information peut être obtenue de plusieurs manières : GPS, Wi-Fi, adresse IP ou réseau mobile.

Dans une application comme Hairbnb, la géolocalisation est utilisée pour :

  • Transformer une adresse postale saisie en coordonnées GPS (géocodage),

  • Proposer une saisie automatique des villes via une recherche intelligente (autocomplétion),

  • Afficher la commune automatiquement en fonction du code postal,

  • Localiser l’utilisateur pour filtrer les coiffeuses par proximité.

5.2. Historique des choix technologiques

Au début du projet, l’API Google Maps était envisagée pour la géolocalisation.

Toutefois, son utilisation implique la saisie d’une carte bancaire valide (non prépayée), même pour accéder au quota gratuit mensuel.[13].

Cette contrainte a motivé l’exploration de solutions open source ou gratuites.

Le premier choix alternatif a été OpenStreetMap, via des API telles que Nominatim.

Bien que gratuite, cette solution s’est révélée lente et peu optimisée pour les appels fréquents ou les opérations simples, ce qui impactait l’expérience utilisateur.

J’ai testé leur carte…​ disons que l’expérience utilisateur m’a donné envie de revenir au bon vieux plan papier. 😅

Le choix final s’est donc porté sur Geoapify, une plateforme de géolocalisation cloud, qui offre :

  • Une API gratuite permettant jusqu’à 3000 requêtes par jour, )ce qui est largement suffisant dans le cadre d’un projet de fin de formation).

  • Un support complet pour la géocodification, l’autocomplétion, les cartes, etc.,

  • Une documentation claire, et un bon rapport performance/simplicité.

5.3. Tableau comparatif : OpenStreetMap vs Geoapify

Critère OpenStreetMap (Nominatim) Geoapify

Modèle de données

Open source (OSM)

Basé sur OSM avec enrichissements

Performance

Moyenne

Bonne (optimisée pour API)

Facilité d’intégration

Moyenne

Facile (endpoints REST + clé API)

Support des fonctions avancées

Limité

Complet (autocomplétion, isochrones, POI…)

Documentation

Basiques

Très bien documentée[14]

Limite gratuite

~1 requête/sec

3000 requêtes/jour gratuites

Clé API requise

Non

Oui

Vitesse d’autocomplétion

Lente

Rapide et fluide

5.4. Cas d’utilisation dans Hairbnb

La géolocalisation a été utilisée dans plusieurs modules de l’application :

  • Autocomplétion de ville : via l’API autocomplete de Geoapify, le champ de saisie de la ville suggère des noms dès les premières lettres tapées. Cela réduit les erreurs et facilite la saisie par l’utilisateur.

  • Conversion d’adresse en coordonnées GPS : lors de l’enregistrement du profil d’une coiffeuse, l’adresse saisie est transformée en coordonnées GPS (lat, lon) via l’endpoint geocode/search.

  • Détection automatique de la commune à partir du code postal : Geoapify permet de récupérer la ville liée à un code postal donné, ce qui simplifie la saisie de l’adresse.

5.5. Fonctionnement sur mobile et navigateur

  • Sur mobile (Flutter) :

    • L’utilisateur saisit une adresse.

    • Un appel HTTP est effectué à l’API Geoapify pour autocomplétion ou géocodage.

    • Les coordonnées ou la ville sont extraites, affichées.

    • Le plugin geolocator peut aussi être utilisé pour obtenir la position GPS actuelle (avec autorisation).

  • Sur navigateur (Flutter Web) :

    • Même logique que sur mobile.

    • Fonctionne correctement tant que le navigateur autorise l’accès à la géolocalisation ou que les requêtes API sont valides.

Une attention particulière a dû être portée à la gestion des fuseaux horaires et des formats d’horodatage pour éviter des incohérences dans l’ordre des données liées à la localisation ou aux messages.

Cette problématique a déjà été rencontrée lors du développement du module de chat.

Par ailleurs, lors de la recherche de coiffeuses à proximité, une permission est demandée à l’utilisateur afin d’accéder à sa localisation actuelle.

Cette étape est nécessaire pour déterminer sa position GPS et filtrer les résultats en fonction de la distance.

5.6. Conclusion sur la gestion de la localisation

En choisissant Geoapify, l’application Hairbnb a bénéficié d’une solution gratuite, performante et bien documentée pour intégrer des fonctionnalités de géolocalisation essentielles.

Ce choix s’est avéré judicieux pour un projet à budget limité, tout en assurant une bonne qualité de service.

6. La platefrome de payment Stripe

6.1. Introduction

L’objectif de cette section est de présenter l’intégration de Stripe comme solution de paiement dans l’application mobile Hairbnb.

Stripe a été choisi pour sa fiabilité, sa documentation claire et sa facilité d’intégration avec Flutter et Django.

6.2. Présentation de Stripe

Stripe est une plateforme de paiement en ligne moderne, utilisée par des milliers d’applications à travers le monde.

Elle permet aux entreprises d’accepter des paiements en ligne de manière sécurisée, rapide et évolutive.

Stripe a été fondée en 2010 par deux frères irlandais, Patrick et John Collison.

Son siège social est situé à San Francisco, aux États-Unis.

Depuis sa création, Stripe a connu une croissance fulgurante et est désormais disponible dans plus de 40 pays, avec une forte adoption en Europe et en Amérique du Nord.[15]

Stripe se positionne comme une solution "developer-first", c’est-à-dire pensée en priorité pour les développeurs.

Son API claire et cohérente, ainsi que ses SDK disponibles pour de nombreuses technologies, en font un choix privilégié pour les applications mobiles comme Hairbnb.

Avantages principaux :

  • Conformité PCI-DSS intégrée.

  • API puissante et bien documentée.

  • Support des paiements par carte bancaire, Apple Pay, Google Pay, etc.

  • Gestion des remboursements, des litiges et des paiements récurrents.

  • Support multi-devises.

  • Compatible avec les modèles marketplace (via Stripe Connect).

6.3. Fonctionnement général du paiement

Le processus de paiement s’organise en plusieurs étapes :

  1. Le client sélectionne un service à réserver.

  2. L’application affiche le montant à payer.

  3. Le client saisit ses informations de paiement.

  4. Une requête est envoyée au backend (Django) pour créer un PaymentIntent.

  5. Le client_secret est retourné au frontend.

  6. Le client valide le paiement dans Flutter via le SDK Stripe.

  7. Stripe notifie le backend via Webhook.

  8. Le backend met à jour l’état de la réservation (confirmée, échouée, etc.).

ConsoleStripe
Figure 2. Stripe console [https://dashboard.stripe.com/]

6.4. Architecture technique

6.4.1. Côté Flutter

  • Utilisation du package flutter_stripe.

  • Initialisation du SDK Stripe avec la clé publique.

  • Récupération du client_secret via un appel à Django.

  • Validation du paiement avec Stripe.instance.confirmPayment(…​).

6.4.2. Côté Django (Backend)

  • Endpoint : POST /create-payment-intent/

  • Authentification via Firebase token.

  • Utilisation de la bibliothèque Stripe Python pour créer le PaymentIntent.

  • Retour du client_secret vers Flutter.

6.4.3. Sécurité

  • Authentification sécurisée entre Firebase et Django.

  • Webhooks protégés avec une clé secrète (STRIPE_WEBHOOK_SECRET).

  • Données sensibles non stockées côté client. (Même principe pour les mots de passe avec firebase)

6.5. Webhooks Stripe

Stripe permet de recevoir des événements (paiement réussi, échec, remboursement, etc.).

  • Route webhook : /webhook/stripe/

  • Vérification de la signature pour chaque appel.

  • Mise à jour du statut de la réservation dans la base de données PostgreSQL.

6.6. Gestion des erreurs

Cas pris en charge :
* Échec du paiement : message d’erreur affiché.
* Annulation par l’utilisateur : retour à l’écran précédent.
* Remboursement partiel ou total : déclenché manuellement ou via interface admin.

6.7. Justification du choix technique

Stripe est une solution moderne, robuste et évolutive, comparée à d’autres solutions comme PayPal ou Mollie :

  • Intégration plus fluide avec Flutter.

  • API REST bien documentée.

  • Meilleur support pour les fonctionnalités marketplace (Stripe Connect).

6.8. Perspectives d’évolution

  • Intégration de Stripe Connect pour les paiements directs aux coiffeuses.

  • Génération automatique de factures PDF.

  • Visualisation des revenus pour les coiffeuses dans leur espace personnel.

6.9. Diagramme de sequence – Paiement Stripe

Diagram

7. La base de données PostgreSQL

7.1. Définition de PostgreSQL

PostgreSQL est un système de gestion de base de données relationnelle (SGBDR) open source, reconnu pour sa robustesse, sa conformité aux standards SQL (ANSI/ISO), et sa grande capacité d’extensibilité.

Il repose sur un modèle relationnel avec des fonctionnalités avancées, comme :
* Les transactions ACID (Atomicité, Cohérence, Isolation, Durabilité)
* Le typage fort
* La prise en charge des types complexes (JSON, géométrie, tableaux, etc.)
* La gestion fine des index, des vues matérialisées et des fonctions stockées

Il est largement utilisé dans les environnements de production critiques, y compris dans des systèmes de grande échelle.

7.2. Historique et évolution

PostgreSQL trouve ses origines dans le projet Ingres, développé à l’Université de Californie à Berkeley dans les années 1970.

En 1986, le professeur Michael Stonebraker lance le projet POSTGRES, qui deviendra par la suite PostgreSQL (Post Ingres SQL), avec l’objectif d’intégrer des concepts relationnels plus avancés (comme les objets, les règles et les requêtes complexes).

Depuis sa première version publique en 1996, PostgreSQL est maintenu par une large communauté internationale et soutenu par de nombreuses entreprises.

Aujourd’hui, il est considéré comme l’un des SGBD open-source les plus puissants, utilisé par des géants comme Instagram, Spotify, Reddit, ou encore Airbnb.[16]

7.3. Pourquoi PostgreSQL ?

PostgreSQL a été choisi pour Hairbnb en raison de :

  • Son excellente compatibilité avec Django via l’ORM natif.

  • Son support des types de données avancés (JSONB, tableaux, géolocalisation avec PostGIS).

  • Sa stabilité et son évolutivité, idéale même pour des projets qui évolueront vers une version SaaS.

  • La nécessité de maintenir des relations fortes et cohérentes entre les entités métier : clients, coiffeuses, services, réservations, etc.

7.4. Rôle de PostgreSQL dans l’architecture

PostgreSQL stocke toutes les données structurées de l’application Hairbnb :

  • Profils utilisateur (coiffeuses et clients)

  • Informations sur les services proposés

  • Détails des réservations

  • Adresses et géolocalisation

  • Historique des paiements (en lien avec les webhooks Stripe)

  • Avis et notations

La base relationnelle assure l’intégrité référentielle, ce qui garantit que, par exemple, une réservation ne peut pas exister sans client ni coiffeuse valide.

7.5. Relation avec Firebase

Firebase gère l’authentification (email/password, Google, etc.).

Chaque utilisateur authentifié reçoit un UID unique.

Dans PostgreSQL, ce UID est stocké dans la table TblUser pour relier un compte Firebase à une entité du modèle Hairbnb.

Cela permet :
* De déléguer la sécurité à Firebase (2FA, récupération de mot de passe, etc.)
* De garder un référentiel unique dans PostgreSQL pour les données métier

7.6. Bonnes pratiques appliquées

  • Indexation sur les colonnes les plus utilisées (UID, email, created_at, etc.)

  • Utilisation de contraintes d’unicité et de clés étrangères pour la cohérence

  • Séparation des responsabilités par modèles Django (classe abstraite, héritage logique)

  • Timestamps automatiques (created_at, updated_at) pour l’historisation

  • Relations explicites OneToMany et ForeignKey dans Django ORM

  • Option envisagée pour la géolocalisation via PostGIS (ex : recherche de coiffeuses proches)

Je voulais utiliser PostGIS pour gérer la géolocalisation en backend, ce qui peut garantir des recherches spatiales précises (par exemple : retrouver les coiffeuses à proximité du client en fonction de la latitude/longitude).
Mais malheureusement, il y avait un problème de dépendance entre la version de PostGIS et la dernière version de Python ou de Django (je ne me rappelle plus exactement). Donc, c’est peut-être quelque chose à envisager pour une future version.

7.6.1. Qu’est-ce que PostGIS ?

PostGIS est une extension de PostgreSQL qui ajoute le support des données géospatiales (coordonnées GPS, polygones, distances, etc.).

Elle permet d’effectuer des requêtes spatiales directement en SQL, comme la recherche de points proches, le calcul de distances, ou l’intersection de zones.

PostGIS transforme PostgreSQL en un véritable Système de Gestion de Bases de Données Spatiales (SGBD-S), conforme aux standards OGC (Open Geospatial Consortium).

7.7. Requêtes typiques et exemples

Voici un exemple de requête pour récupérer les réservations d’un client :

SELECT r.date, s.nom_service, c.nom AS nom_coiffeuse
FROM tblreservation r
JOIN tblservice s ON r.service_id = s.id
JOIN tblcoiffeuse c ON s.coiffeuse_id = c.id
WHERE r.client_id = <id_client>;

7.8. Utilisation de l’ORM Django

7.8.1. Qu’est-ce qu’un ORM ?

Un ORM (Object-Relational Mapping, ou mappage objet-relationnel) est un outil qui permet de manipuler une base de données relationnelle à l’aide d’objets dans un langage de programmation orienté objet, sans avoir à écrire directement des requêtes SQL.

Dans le cas de Django, l’ORM est intégré nativement dans le framework et permet aux développeurs de créer, lire, mettre à jour et supprimer des données (opérations CRUD) en utilisant uniquement du code Python.

Cela améliore la lisibilité, la productivité et réduit le risque d’erreurs liées à des requêtes SQL mal formulées.

7.8.2. Avantages de l’ORM Django

  • Abstraction complète du SQL : pas besoin d’écrire une seule ligne de requête SQL.

  • Portabilité : le même code peut fonctionner avec plusieurs SGBD (PostgreSQL, SQLite, MySQL…).

  • Validation automatique des données via les modèles.

  • Typage clair et relations explicites entre les entités (ForeignKey, ManyToMany, etc.).

  • Génération automatique des schémas via les migrations.

7.8.3. Qu’est-ce que le « mapping » objet-relationnel ?

Le mapping correspond à la correspondance entre une classe Python et une table SQL.

Par exemple :

class Coiffeuse(models.Model):
    nom = models.CharField(max_length=100)
    prenom = models.CharField(max_length=100)
    specialites = models.TextField()

Cela correspondrait à une table SQL comme :

CREATE TABLE coiffeuse (
    id SERIAL PRIMARY KEY,
    nom VARCHAR(100),
    prenom VARCHAR(100),
    specialites TEXT
);

Chaque instance de la classe Coiffeuse en Python correspond à une ligne (ou "row") dans la table SQL.

7.8.4. Qu’est-ce qu’une migration ?

Une migration est un fichier auto-généré par Django qui contient les instructions nécessaires pour créer, modifier ou supprimer des tables dans la base de données.

Elle est créée via la commande :

python manage.py makemigrations

Et appliquée à la base de données avec :

python manage.py migrate

Cela garantit que le schéma de la base de données est toujours synchronisé avec le code Python.

7.8.5. Exemples de manipulation sans requêtes SQL

Créer une nouvelle coiffeuse :

c = Coiffeuse(nom="Elena", prenom="Dupont", specialites="Coloration, tresses africaines")
c.save()

Récupérer toutes les coiffeuses :

Coiffeuse.objects.all()

Rechercher une coiffeuse par nom :

Coiffeuse.objects.filter(nom="Elena")

Mettre à jour un champ :

c = Coiffeuse.objects.get(id=1)
c.nom = "Éléonore"
c.save()

Supprimer un enregistrement :

c.delete()

Ces opérations sont automatiquement traduites par Django en requêtes SQL optimisées, sans intervention manuelle.

8. Le Framework Django

8.1. Introduction

Dans l’architecture de l’application Hairbnb, le backend joue un rôle central.

Il est développé avec le framework Django, qui offre un environnement robuste, sécurisé et modulaire pour construire une API performante.

Django est chargé de toute la logique côté serveur, en lien avec les fonctionnalités suivantes :

  • La gestion métier : Django applique les règles de fonctionnement spécifiques à l’application.

Par exemple :
Si un client tente de réserver un service à une date où la coiffeuse est déjà occupée, le système lui renverra un message d’erreur indiquant que le créneau n’est plus disponible.
Lorsqu’un client envoie une demande de réservation, seule la coiffeuse concernée a le droit de confirmer ou de refuser ce rendez-vous.

  • L’interaction avec la base de données PostgreSQL : via l’ORM de Django, le backend peut créer, lire, modifier ou supprimer des données sans écrire une seule ligne de SQL.

  • La gestion de la sécurité des échanges entre Flutter (le frontend) et le backend : + autorisation selon les rôles (client ou coiffeuse), et validation des identifiants Firebase.

  • La communication avec Flutter : Django expose des endpoints RESTful structurés, qui permettent à l’application mobile d’accéder aux ressources (coiffeuses, services, réservations, etc.).

  • La gestion des paiements via Stripe : le backend est responsable de créer les PaymentIntent, de sécuriser la transaction, et de traiter les webhooks envoyés par Stripe après le paiement.

  • L’ouverture à des services tiers : l’architecture Django permet une intégration future simple avec d’autres systèmes comme l’envoi d’emails de confirmation, la synchronisation d’agenda (Google Calendar), ou encore des outils de statistiques internes.

Le choix de Django s’inscrit dans une volonté de construire un backend fiable, évolutif et documenté, aligné avec les bonnes pratiques modernes du développement web et mobile.

8.2. 2. Qu’est-ce que Django ?

Django est un framework web open-source écrit en Python, conçu pour le développement rapide d’applications web sécurisées, performantes et maintenables.

Il repose sur le principe "Don’t Repeat Yourself" (DRY), qui vise à éviter les répétitions inutiles dans le code, et sur le concept de réutilisabilité des composants.

8.2.1. Historique de Django

Django a été créé en 2003 par Adrian Holovaty et Simon Willison, deux développeurs travaillant pour un journal local aux États-Unis.

Leur objectif était de simplifier le développement de sites d’information complexes et dynamiques.

À l’origine, Django a été développé par deux développeurs travaillant pour un petit journal local.
Aujourd’hui, ce framework est utilisé dans le monde entier, y compris par des géants comme Instagram ou Pinterest.
Comme quoi, deux développeurs dans une salle de rédaction peuvent créer un outil qui révolutionne le développement web !😄

Le projet a été rendu public en 2005, sous licence BSD, et depuis lors, Django est devenu l’un des frameworks web Python les plus populaires au monde, utilisé par des entreprises comme Instagram, Mozilla, Pinterest ou encore The Washington Post.

Il est maintenu par la Django Software Foundation (DSF), une organisation à but non lucratif dédiée à son développement.

8.3. Python : le langage de base de Django

Django est écrit en Python, un langage de programmation interprété, orienté objet, et très lisible.

8.3.1. Historique de Python

Python a été créé en 1991 par Guido van Rossum, aux Pays-Bas, avec l’objectif de proposer un langage simple, clair et intuitif.

Il est aujourd’hui l’un des langages les plus utilisés au monde, aussi bien pour le web que pour la science des données, l’automatisation ou l’intelligence artificielle.

Ses principales qualités :
* Syntaxe lisible et proche du langage humain
* Écosystème riche (bibliothèques, frameworks, outils)
* Multiplateforme et polyvalent
* Fortement utilisé dans l’enseignement et la recherche

Python est publié sous licence open source, et son développement est supervisé par la Python Software Foundation (PSF).

8.3.2. Architecture MTV et séparation des responsabilités

Django repose sur une architecture dite MTV (Model - Template - View), inspirée du modèle MVC classique.

Cette organisation permet une séparation claire des responsabilités dans l’application.

  • Model : C’est la couche des données.
    Elle définit la structure des objets métier et leur représentation en base de données (ex. : TblUser, TblReservation).
    Chaque classe correspond à une table SQL.

  • View : Elle contient la logique de traitement : elle reçoit une requête, interagit avec les modèles, et renvoie une réponse (souvent JSON dans le cas d’une API).

  • Template : Cette couche sert à générer du contenu HTML.
    Dans Hairbnb, elle n’est pas utilisée puisque l’affichage est géré par Flutter côté client.

Dans le cas d’une API REST (comme pour Hairbnb), les Templates sont remplacés par des Serializers (via Django REST Framework), qui permettent de transformer les objets Python en JSON.
Diagram

8.4. Django REST Framework (DRF)

Django REST Framework (ou DRF) est une bibliothèque puissante construite au-dessus de Django, conçue pour créer facilement des APIs web RESTful.

Elle est utilisée dans Hairbnb pour permettre à l’application mobile Flutter de communiquer avec le backend de manière structurée et sécurisée.

8.4.1. Pourquoi utiliser DRF dans Hairbnb ?

Le projet Hairbnb nécessite une API accessible depuis une application mobile.

DRF répond parfaitement à ce besoin en fournissant :

  • Une architecture claire et modulaire (vues, serializers, permissions…)

  • Une sérialisation automatique des données entre les objets Django et le format JSON

  • Une prise en charge native de l’authentification (ce n’est pas le cas de Hairbnb), des permissions, de la pagination et des erreurs

  • Une documentation interactive (avec Browsable API) très utile en phase de développement

8.4.2. Principales fonctionnalités utilisées

  • Sérialisation Le Serializer permet de convertir un modèle Django (ex : Reservation) en JSON exploitable par Flutter, et inversement.

    Exemple :
    [source,python]
    class ReservationSerializer(serializers.ModelSerializer):
        class Meta:
            model = Reservation
            fields = '__all__'
  • VueSet ViewSet regroupe les actions (GET, POST, PUT, DELETE) sur un modèle en une seule classe.

    Exemple :
    [source,python]
    class ReservationViewSet(viewsets.ModelViewSet):
        queryset = Reservation.objects.all()
        serializer_class = ReservationSerializer
        permission_classes = [IsAuthenticated]
  • Routage automatique DRF permet de générer automatiquement les routes API à partir des ViewSet via un DefaultRouter.

    [source,python]
    router = DefaultRouter()
    router.register(r'reservations', ReservationViewSet)

Ce code crée automatiquement les endpoints suivants :
- GET /reservations/ : liste des réservations
- POST /reservations/ : création
- GET /reservations/<id>/ : détail
- PUT /reservations/<id>/ : mise à jour
- DELETE /reservations/<id>/ : suppression

8.4.3. Qu’est-ce qu’un Router dans Django REST Framework ?

Dans Django REST Framework, un Router est un composant qui permet de générer automatiquement les routes URL d’une API à partir des ViewSet.

Plutôt que d’écrire manuellement les chemins (urls.py) pour chaque opération (liste, détail, création, suppression…), le Router crée toutes les URL nécessaires en se basant sur le nom du modèle et les méthodes du ViewSet.

Par exemple, avec ce code :

from rest_framework.routers import DefaultRouter
from .views import ReservationViewSet

router = DefaultRouter()
router.register(r'reservations', ReservationViewSet)

DRF crée automatiquement les routes suivantes :
* GET /reservations/ → liste des réservations
* POST /reservations/ → création
* GET /reservations/<id>/ → détail d’une réservation
* PUT /reservations/<id>/ → mise à jour
* DELETE /reservations/<id>/ → suppression

Le Router permet donc :
* Un gain de temps dans le développement
* Une uniformisation des routes de l’API
* Une intégration directe avec la logique RESTful de ViewSet

Contrairement à l’usage courant du Router dans Django REST Framework, le projet Hairbnb utilise une approche manuelle pour définir les routes de l’API.
Chaque endpoint est ajouté explicitement dans le fichier urls.py, ce qui permet un contrôle plus précis sur les chemins, les noms de vues et les autorisations.
Cette méthode est particulièrement utile dans un projet en phase MVP où l’on souhaite garder la main sur chaque route définie.

8.4.4. Communication avec Flutter

Flutter envoie des requêtes HTTP vers les endpoints exposés par DRF.

Chaque réponse est retournée au format JSON, ce qui permet une conversion facile en objets Dart côté client.

Exemple côté Flutter (pseudo-code) :

final response = await http.get(
  Uri.parse('https://hairbnb-api.com/api/reservations/'),
  headers: {'Authorization': 'Bearer <FirebaseToken>'},
);

if (response.statusCode == 200) {
  final data = jsonDecode(response.body);
  // mapping vers modèle Dart
}

DRF joue donc un rôle essentiel dans l’architecture de Hairbnb : il assure le pont fiable et sécurisé entre Flutter et la base de données via Django.

8.5. Interaction avec PostgreSQL via l’ORM

Dans le projet Hairbnb, l’interaction entre le backend Django et la base de données PostgreSQL est assurée par l’ORM intégré (Object-Relational Mapping).

Cet ORM permet de manipuler la base de données sans écrire directement de requêtes SQL : toutes les opérations se font via des objets Python.

8.5.1. Mapping des classes Python vers les tables SQL

Chaque modèle Django (ex : Reservation, UserProfile, Salon) est défini comme une classe Python.

Lors de l’exécution des migrations, Django convertit ces classes en tables SQL dans la base PostgreSQL.

class Reservation(models.Model):
    client = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateTimeField()
    status = models.CharField(max_length=20)

Ce code crée une table reservation avec trois colonnes (client_id, date, status) et une clé étrangère vers la table auth_user.

8.5.2. Création et migration du schéma

Le schéma de la base est construit automatiquement grâce aux commandes Django :

python manage.py makemigrations
python manage.py migrate

La première commande génère un fichier de migration basé sur les modèles Python.

La seconde applique ce fichier et crée (ou modifie) les tables SQL dans PostgreSQL.

8.5.3. Opérations CRUD avec Model.objects

L’ORM permet de faire toutes les opérations classiques (Create, Read, Update, Delete) via une syntaxe Python simple :

# Création
Reservation.objects.create(client=user, date=now(), status='en attente')

# Lecture
Reservation.objects.filter(client=user)

# Modification
reservation.status = 'confirmée'
reservation.save()

# Suppression
reservation.delete()

Derrière chaque instruction se cache une requête SQL générée automatiquement.

8.5.4. Relations, indexation et contraintes

Django prend en charge plusieurs types de relations :

  • ForeignKey : relation 1-n (ex : une réservation → un client)

  • ManyToManyField : relation n-n (ex : un salon avec plusieurs services)

  • OneToOneField : relation 1-1 (ex : UserUserProfile)

L’ORM permet aussi de définir des contraintes de type unique, null, blank, etc., ainsi que des indexes pour améliorer les performances de requêtes complexes.

8.5.5. Avantages de l’ORM Django

  • Simplifie la gestion de la base de données

  • Réduit le risque d’erreur SQL manuelle

  • Offre une abstraction unifiée entre les modèles

8.6. Sécurisation des échanges (Flutter ↔ Django)

Dans le projet Hairbnb, la sécurité des échanges entre le frontend Flutter et le backend Django est une priorité essentielle, notamment pour l’authentification, la protection des données personnelles et le contrôle des accès selon les rôles (client ou coiffeuse).

8.6.1. Authentification via Firebase

L’authentification est déléguée à Firebase Authentication, qui gère l’inscription, la connexion et la vérification des utilisateurs.

Lorsque l’utilisateur se connecte via l’app Flutter, Firebase retourne un ID token sécurisé (JWT signé par Google).

Ce token est ensuite inclus dans les appels API :

headers: {
  "Authorization": "Bearer <Firebase_ID_Token>"
}

Côté backend, ce token est extrait et vérifié dans les requêtes entrantes pour authentifier l’utilisateur.

8.6.2. Vérification du Firebase UID côté Django

Chaque utilisateur authentifié par Firebase possède un identifiant unique (UID).

Dans Hairbnb, ce UID est associé à une entrée dans la base PostgreSQL (TblUser) pour lier le compte Firebase au modèle interne.

Le backend utilise une vérification du token Firebase (via la bibliothèque officielle firebase-admin) pour extraire le UID, le comparer avec la base, et accorder ou non l’accès à l’API.

from firebase_admin import auth

def verify_firebase_token(token):
    decoded = auth.verify_id_token(token)
    return decoded['uid']

8.6.3. Middleware ou décorateur personnalisé

Pour centraliser la sécurité, un middleware ou un décorateur Django est utilisé afin de :

  • Extraire le token depuis l’en-tête HTTP

  • Vérifier sa validité avec Firebase

  • Authentifier ou refuser la requête selon les résultats

Cela permet de sécuriser toutes les routes sensibles sans dupliquer la logique d’authentification.

def firebase_authenticated(view_func):
    """
    Décorateur qui vérifie si l'utilisateur est authentifié via Firebase.
    Si l'utilisateur n'est pas authentifié, renvoie une réponse 401.
    """

    @wraps(view_func)
    def _wrapped_view(request, *args, **kwargs):
        if not request.user or not hasattr(request.user, 'uuid'):
            return Response({"detail": "Authentification requise"}, status=401)
        return view_func(request, *args, **kwargs)

    return _wrapped_view

8.6.4. Permissions DRF selon les rôles

Le système de rôles est essentiel dans Hairbnb, car les droits sont différents entre les clients et les coiffeuses.

Les permissions sont implémentées via les classes de Django REST Framework :

  • IsAuthenticated : accès seulement si l’utilisateur est connecté

  • IsCoiffeuse : accès restreint aux utilisateurs avec un rôle spécifique

  • IsOwnerOrReadOnly : l’utilisateur peut voir, mais ne modifier que ses propres données

Exemple de permission personnalisée :

class IsCoiffeuse(BasePermission):
    def has_permission(self, request, view):
        return request.user.role == 'coiffeuse'

Ces permissions sont ensuite ajoutées aux ViewSet pour contrôler l’accès à chaque ressource de manière fine et sécurisée.

8.6.5. Résultat

Grâce à cette architecture :
* Le backend Django ne stocke pas les mots de passe
* L’identité de l’utilisateur est validée de façon sécurisée via Firebase
* L’accès à l’API est contrôlé selon des rôles précis
* Chaque requête est traçable et isolée par utilisateur

Cette approche renforce la sécurité globale de la plateforme Hairbnb tout en simplifiant la gestion des comptes et des autorisations.

8.7. Architecture des fichiers et bonnes pratiques

Le projet Hairbnb suit l’architecture classique recommandée par le framework Django, en combinant les bonnes pratiques de modularisation et les spécificités de Django REST Framework.

8.7.1. Structure générale d’une application Django

Chaque fonctionnalité du projet (utilisateurs, réservations, paiements, etc.) est organisée dans une application Django indépendante, selon le principe de séparation des responsabilités.

Chaque app contient ses propres fichiers métier, ce qui rend le projet plus clair, maintenable et évolutif.

Voici les principaux fichiers utilisés dans chaque app :

  • models.py Contient la définition des modèles de données. Chaque classe représente une table dans PostgreSQL, avec ses champs et ses relations.

  • serializers.py Définit la conversion entre les objets Python et le format JSON.
    Les serializers sont utilisés pour lire ou écrire les données via l’API REST.

  • views.py Implémente la logique de traitement. Dans Hairbnb, on utilise souvent des ViewSet de DRF pour regrouper les actions CRUD d’un même modèle.

  • urls.py Ce fichier déclare les routes accessibles de l’API pour chaque app. Contrairement à l’usage du DefaultRouter, Hairbnb préfère une configuration manuelle des endpoints pour plus de contrôle.

  • permissions.py Contient les règles de sécurité personnalisées selon le rôle (client, coiffeuse, admin…), utilisées pour restreindre l’accès à certaines ressources ou actions.

8.7.2. Exemple de structure pour l’app reservation

reservation/
├── __init__.py
├── models.py
├── serializers.py
├── viewsets.py
├── urls.py
├── permissions.py

Chaque app est ainsi autonome, testable et facile à intégrer dans d’autres projets.

8.7.3. Bonnes pratiques appliquées

  • Respect strict de la convention Django : nommage des fichiers, gestion des migrations, import explicite

  • Séparation logique des responsabilités : chaque couche a un rôle clair (modèle / vue / sérialiseur)

  • Centralisation de la sécurité : permissions personnalisées regroupées dans permissions.py

  • API REST conçue avec des endpoints explicites, sécurisés et documentés

  • Modularité : chaque domaine fonctionnel (user, reservation, paiement, etc.) peut évoluer indépendamment

8.7.4. Avantages de cette organisation

  • Maintenance facilitée : chaque composant est localisé dans une app dédiée

  • Réutilisabilité : les composants sont indépendants et cohérents

  • Lisibilité : la structure reflète l’architecture métier du projet

  • Evolutivité : ajout de nouvelles apps ou modules possible sans casser l’existant

Cette architecture modulaire, combinée aux bonnes pratiques Django/DRF, permet à Hairbnb de rester une base de code propre, robuste et prête à évoluer vers des versions futures.

8.7.5. 8.5 Évolution vers une architecture plus maintenable

Au départ, le projet Hairbnb suivait une structure Django classique, où chaque app contenait un seul fichier views.py, urls.py ou serializers.py.

Cependant, à mesure que le projet grandissait, cette approche a montré ses limites : les fichiers devenaient trop longs, denses, et peu lisibles.

Il devenait difficile de :

  • Retrouver une vue spécifique parmi plusieurs centaines de lignes

  • Comprendre rapidement la logique métier associée à une route

  • Maintenir des modules sans casser accidentellement une autre partie

Pour répondre à ces problèmes, l’architecture du backend a été refondue autour d’un principe clé : une structure par domaine fonctionnel, propre et isolée dans un dossier apps/.

8.7.6. Nouvelle structure adoptée (Hairbnb)

hairbnb_backend/
├── manage.py
├── requirements.txt
├── hairbnb/
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── apps/
│   ├── users/
│   │   ├── models.py (UserProfile)
│   │   ├── serializers.py (UserSerializer)
│   │   ├── views.py (ProfileViewSet)
│   │   └── urls.py
│   ├── salons/
│   │   ├── models.py (Salon, Service)
│   │   ├── serializers.py (SalonSerializer)
│   │   ├── views.py (SalonDetailView)
│   │   └── urls.py
│   ├── conversations/
│   │   ├── models.py (Conversation, Message)
│   │   ├── serializers.py (ConversationSerializer)
│   │   ├── views.py (ConversationViewSet)
│   │   └── urls.py
│   └── bookings/
│       ├── models.py (Reservation)
│       ├── serializers.py
│       └── views.py

Chaque sous-dossier dans apps/ représente une fonctionnalité métier autonome.

Il regroupe tous les fichiers nécessaires à son fonctionnement : modèle, sérialiseur, vue, URL.

Cela permet de :

  • Isoler la logique métier par domaine (users, salons, réservations…)

  • Accéder rapidement à un module précis sans naviguer dans de gros fichiers

  • Améliorer la lisibilité et la maintenabilité du code

  • Faciliter l’ajout de tests unitaires et l’extension future

Je ne sais pas s’il existe une structure officielle ou documentée qui corresponde exactement à ce modèle, mais c’est une organisation que j’ai mise en place moi-même, de manière empirique.
Je l’ai trouvée plus logique, plus intuitive, et surtout beaucoup mieux adaptée à mes besoins réels en termes de lisibilité, de maintenabilité et d’efficacité au quotidien.
Ce changement d’organisation a eu un impact très positif sur le développement quotidien.
Aujourd’hui, lorsque je cherche une vue, une route ou un modèle, je sais exactement dans quel dossier aller.
Cela réduit fortement la perte de temps, les erreurs de duplication, et rend le projet beaucoup plus clair.
— Experience personnelle

9. Flutter & son ecosysteme

9.1. Qu’est-ce que Flutter ?

Flutter est un framework open-source développé par Google, permettant de créer des applications mobiles, web et desktop à partir d’un seul code source.

Il repose sur un moteur graphique performant (Skia) et permet de concevoir des interfaces fluides, modernes et réactives, en natif.

Flutter suit le principe du widget-first : tout est un widget, qu’il s’agisse de texte, de boutons, ou même de mise en page.

9.2. Historique de Flutter

  • 2017 : Google publie la première version bêta de Flutter

  • 2018 : sortie officielle de Flutter 1.0

  • 2021 : Flutter 2 introduit le support multiplateforme (web, desktop)

  • 2023 : Flutter 3 et l’intégration plus poussée avec Material 3

Aujourd’hui, Flutter est largement utilisé dans le monde professionnel (ex : Alibaba, BMW, Google Pay) et par la communauté open-source.

9.3. Qu’est-ce que Dart ?

Dart est un langage de programmation orienté objet, développé également par Google.

Il est le langage officiel utilisé avec Flutter.

Son objectif est de combiner la rapidité d’un langage compilé avec la flexibilité d’un langage interprété.

Dart est :

  • Typé statiquement, mais souple (grâce au type inference)

  • Inspiré de langages comme JavaScript, Java et C#

  • Capable d’être compilé en code natif ou en JavaScript pour le web

9.4. Historique de Dart

  • 2011 : création de Dart par Google

  • 2013 : première version stable

  • 2018 : Dart devient le langage principal de Flutter

  • 2022 : introduction du null safety obligatoire

  • 2024 : Dart continue d’évoluer, notamment avec Dart 3+

9.5. Kotlin (mentionnée pour Android)

Kotlin est un langage moderne développé par JetBrains, interopérable avec Java, et officiellement supporté par Google pour le développement Android depuis 2017.

Il est utilisé dans les projets Android natifs, mais n’est pas directement utilisé dans Flutter, sauf dans des cas très spécifiques (intégration de plugins natifs ou Firebase).

Dans Hairbnb, Kotlin peut apparaître côté Android dans la configuration des plugins (ex : Firebase, Stripe), mais le cœur de l’app est 100 % écrit en Dart.

9.5.1. Qu’est-ce que Gradle ?

Gradle est un outil d’automatisation de build largement utilisé dans les projets Java et Android. Il permet de gérer les dépendances, compiler le code, générer les APK, exécuter les tests, etc.

Dans un projet Flutter, Gradle est utilisé en arrière-plan, lors de la compilation Android, pour orchestrer les tâches comme l’intégration de plugins natifs (firebase_auth, stripe, etc.).

Exemple : Lorsqu’on exécute flutter build apk, c’est Gradle qui génère l’APK Android à partir du code Dart compilé.

9.6. Architecture recommandée dans Flutter : le modèle MVVM

9.6.1. Définition de MVVM

`MVVM`[17] signifie Model – View – ViewModel.
C’est un pattern d’architecture qui sépare clairement les responsabilités au sein d’une application :

  • Model : contient les données, les classes métiers, les formats JSON (user.dart, salon.dart, etc.)

  • View : représente l’interface utilisateur, les widgets visibles (screens, pages)

  • ViewModel : gère la logique métier, l’état de l’application, les interactions avec les services (controllers, providers, etc.)

Ce modèle est largement utilisé dans Flutter, notamment avec des outils comme Provider, Riverpod ou Bloc.

9.6.2. Objectifs de MVVM

  • Séparation des responsabilités : l’UI ne contient pas de logique métier

  • Réutilisabilité du code métier (dans d’autres vues ou tests)

  • Testabilité : les ViewModels peuvent être testés indépendamment

  • Clarté du code : chaque couche a un rôle clair et isolé

9.6.3. Exemple d’organisation MVVM

lib/
├── models/             # Données (Model)
│   └── user.dart
├── views/              # UI (View)
│   └── login_screen.dart
├── viewmodels/         # Logique (ViewModel)
│   └── login_viewmodel.dart
├── services/           # Appels API, Firebase, DB, etc.
└── main.dart

Dans cette structure :
- La View affiche les données (et écoute les changements d’état)
- Le ViewModel écoute les interactions utilisateur, met à jour l’état
- Le Model représente les données brutes (souvent liées aux réponses d’API)

9.6.4. Utilisation typique dans Flutter

Flutter n’impose pas une architecture unique, mais MVVM est compatible avec des solutions comme[18] :

  • Provider (approche simple et intégrée)

  • Riverpod (plus moderne, robuste, déclaratif)

  • Bloc (orientée flux, plus stricte, inspirée de Rx)

Chaque projet peut adapter ce pattern selon sa complexité.
Dans Hairbnb, une structure proche de MVVM a été adoptée, avec une organisation par dossier fonctionnel, enrichie par une logique métier placée dans des services et providers.


1. https://en.wikipedia.org/wiki/PyCharm , PyCharm
2. https://www.jetbrains.com/help/pycharm/django-support.html , Django
3. https://www.jetbrains.com/phpstorm/ , PhpStorm
4. https://plugins.jetbrains.com/plugin/7391-asciidoc , AsciiDoc
5. https://firebase.google.com/ , Firebase
6. https://firebase.google.com/docs/auth/flutter/start?hl=fr
7. https://firebase.google.com/docs/admin/setup?hl=fr , Firebase SDK
8. https://firebase.google.com/docs ,sdktypes
9. https://firebase.flutter.dev/docs/overview, sdkflutter
10. https://firebase.google.com/docs/admin/setup?hl=fr ,sdkadmin
11. https://firebase.google.com/docs/firestore ,firestore_doc
12. https://firebase.google.com/docs/firestore/query-data/listen, firestore_realtime
13. https://developers.google.com/maps/billing-and-pricing/overview?hl=fr ,googlemaps,
14. https://www.geoapify.com/ ,geoapify
15. https://fr.wikipedia.org/wiki/Stripe ,stripe https://www.forbes.com/companies/stripe/ , stripe sur forbes
16. https://www.postgresql.org/docs/current/history.html , History of PostgreSQL
17. https://docs.flutter.dev/app-architecture/case-study , flutter-mvvm
18. https://docs.flutter.dev ,flutter documentation