☁️ 2.6 Persistance cloud et Backend-as-a-Service (BaaS)
Module 335 – Réaliser une application pour mobile
🎯 Objectif d'apprentissage
À la fin de ce chapitre, vous serez capables de :
-
Expliquer ce qu’est un Backend-as-a-Service (BaaS) et pourquoi il facilite le développement mobile
-
Comprendre l’intérêt du cloud dans une application moderne
-
Faire la différence entre Supabase, Firebase, Appwrite, AWS Amplify, etc.
-
Gérer des données distantes (CRUD), la synchro cloud ↔ local et la gestion des permissions
-
Intégrer dans une app mobile :
- une base de données distante
- du stockage de fichiers
- des fonctions serverless
- des notifications push
- une authentification utilisateur
🤔 2.6.1 Introduction : pourquoi un backend cloud ?
Les applications mobiles modernes doivent :
- synchroniser des données entre appareils
- gérer des profils utilisateurs
- fonctionner de manière fluide sur plusieurs appareils
Cela implique généralement :
- une base de données distante
- une API (lectures / écritures)
- une authentification
- du stockage de fichiers (images, PDF…)
- des fonctions serveur
- une gestion des permissions
2.6.1 Problème sans BaaS
Créer tout cela à la main signifie :
- gérer un serveur (hébergement, OS, mises à jour)
- coder une API (REST / GraphQL)
- assurer la sécurité (auth, permissions, protections)
- gérer la scalabilité (beaucoup d’utilisateurs ?)
- maintenir le tout dans le temps
💥 Résultat : long, coûteux, complexe… surtout pour un projet mobile “simple”.
2.6.1 Ce qu’apporte un backend cloud
Un backend cloud apporte :
- Stockage et sauvegarde automatiques des données
- Données accessibles depuis n’importe quel appareil
- Mises à jour instantanées via des API
- Automatisation du “travail serveur” : → authentification, règles de sécurité, fichiers, logs, etc.
- Aucune gestion directe de : → serveurs, mises à l’échelle, monitoring bas niveau
💡 Pour un module pédagogique ou une app interne, un BaaS est souvent le meilleur compromis.
2.6.1 Exemple concret
Exemple : une app où des élèves stockent leurs notes et photos de projets.
- L’élève change de téléphone
- Il se reconnecte
- ✅ Toutes ses données sont déjà là : stockées dans le cloud
🏭 2.6.2 Qu’est-ce qu’un Backend-as-a-Service (BaaS) ?
Un BaaS = un backend prêt à l’emploi, hébergé dans le cloud.
Il fournit les briques principales d’un backend moderne, sans :
- installer de serveur
- configurer un environnement
- coder soi-même toutes les API
2.6.2 Ce qu’un BaaS fournit généralement
- 🔏 Authentification (email, OAuth, social login, magic link, etc.)
- 🗄️ Base de données distante (SQL ou NoSQL)
- 🖼️ Stockage de fichiers (images, vidéos, PDF, etc.)
- 🌐 API générée automatiquement
- ⚙️ Fonctions serverless (exécution de code côté serveur)
- 🔔 Notifications push
- 🛡️ Gestion des rôles / permissions
- 📊 Logs & analytics
2.6.2 Avantages d’un BaaS
-
Aucune infrastructure à gérer (backups, patchs, sécurité bas niveau)
-
Développement rapide grâce aux SDK et API prêtes à l’emploi
-
Sécurité intégrée : permissions, règles d’accès, JWT, etc.
-
Scalabilité automatique (le service s’adapte à la charge)
-
Particulièrement adapté aux apps mobiles :
- data synchronisée
- auth utilisateurs
- fichiers
2.6.2 Limites d’un BaaS
-
Dépendance au fournisseur (vendor lock-in)
-
Coûts qui peuvent augmenter avec :
- le nombre d’utilisateurs
- le volume de données
- les requêtes réseau
-
Moins flexible qu’un backend 100 % sur mesure
💬 Dans un contexte pédagogique ou de projet interne, ces limites sont souvent acceptables.
🧱 2.6.3 Comment fonctionne une base cloud ?
Cycle classique d’un échange entre une app mobile et un backend cloud :
- Authentification (login, tokens)
- Requêtes signées (headers avec token)
- Application des permissions côté backend
- Réponse JSON
- Mise à jour du stockage local
- Gestion du mode offline + synchronisation
2.6.3 Étape 1 – L’utilisateur se connecte
L’utilisateur saisit : email + mot de passe (ou Google, Apple, etc.).
L’app envoie ces infos au backend :
POST /auth/v1/token HTTP/1.1
Host: api.mon-backend.com
Content-Type: application/json
{
"email": "user@example.com",
"password": "super-secret"
}
Le backend :
-
vérifie les identifiants
-
génère un JWT (JSON Web Token) avec :
user_id- rôles / permissions
- date d’expiration
2.6.3 Étape 1 – Stockage du token
L’app stocke ensuite le token dans un stockage sécurisé :
// Exemple pseudo-code avec SecureStorage
await SecureStorage.set({
key: 'access_token',
value: jwtToken
})
🔐 À partir de là, l’app n’envoie plus le mot de passe, uniquement le token à chaque requête.
2.6.3 Étape 2 – L’app envoie une requête au backend
À chaque appel au backend, l’app ajoute :
GET /rest/v1/notes HTTP/1.1
Host: api.mon-backend.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
En TypeScript (Ionic + fetch) :
const token = await SecureStorage.get({ key: 'access_token' })
const res = await fetch('https://api.mon-backend.com/rest/v1/notes', {
headers: {
Authorization: `Bearer ${token.value}`,
'Content-Type': 'application/json'
}
})
const data = await res.json()
2.6.3 Étape 3 – Permissions côté backend
Côté backend, pour chaque requête :
-
Vérification du token (signature, expiration)
-
Lecture des claims (ex.
user_id,role) -
Application des règles de sécurité :
- l’utilisateur peut-il lire ces données ?
- a-t-il le droit de modifier cet élément ?
- est-il propriétaire de la ressource ?
Exemple de règle (pseudo-SQL) :
-- Un utilisateur ne peut lire que ses propres notes
SELECT * FROM notes
WHERE user_id = auth.uid();
Si la permission est refusée →
401ou403.
2.6.3 Étape 4 – Réponse JSON
Si tout est OK, le backend renvoie un JSON adapté à l’utilisateur.
Exemple Supabase :
GET /rest/v1/notes?user_id=eq.214 HTTP/1.1
Host: xyz.supabase.co
Authorization: Bearer <token>
apikey: <public-anon-key>
Réponse :
[
{
"id": 42,
"user_id": 214,
"title": "Note de cours",
"content": "Backend as a Service",
"created_at": "2025-11-19T10:15:00Z"
}
]
L’app :
- reçoit ce JSON
- met à jour son store / composants
2.6.3 Étape 5 – Mise à jour de la base locale
Pour un usage fluide et offline-first, l’app garde une copie locale :
- base locale (SQLite, IndexedDB, Hive, etc.)
- et/ou store (Pinia, Redux) persisté
Exemple pseudo-code (Pinia) :
const useNotesStore = defineStore('notes', {
state: () => ({
notes: [] as Note[]
}),
actions: {
async fetchNotes() {
const token = await SecureStorage.get({ key: 'access_token' })
const res = await fetch('https://api.mon-backend.com/rest/v1/notes', {
headers: { Authorization: `Bearer ${token.value}` }
})
this.notes = await res.json()
// TODO: sauvegarder aussi en local (SQLite / Capacitor Storage)
}
}
})
✅ Interface réactive et responsive, même après redémarrage.
2.6.3 Étape 6 – Offline + synchronisation
Quand l’app est hors ligne :
-
les actions utilisateur sont stockées localement (queue)
-
exemples :
CREATE_NOTEUPDATE_NOTEDELETE_NOTE
Exemple de type :
type PendingAction = {
type: 'CREATE_NOTE' | 'UPDATE_NOTE' | 'DELETE_NOTE'
payload: any
createdAt: string
}
La queue peut être stockée :
- en table locale (SQLite)
- en fichier
- ou en storage clé–valeur
2.6.3 Étape 6 – Replay de la queue
Dès que la connexion revient :
- l’app envoie les actions de la queue au backend
- supprime celles qui ont réussi
- récupère une version à jour des données
💡 Même modèle que l’on utilise avec Supabase, Firebase, Appwrite, etc. Auth → token → requêtes signées → règles de sécurité → JSON → cache local → sync offline.
⚡ 2.6.4 Supabase – une plateforme SQL moderne et ouverte
Supabase = BaaS construit autour de PostgreSQL.
Objectif : une alternative open-source aux solutions propriétaires, basée sur des standards :
- SQL
- REST
- JWT
- permissions explicites
2.6.4 Supabase – Base de données SQL prête à l’emploi
Supabase repose sur PostgreSQL :
-
données structurées dans des tables
-
relations, contraintes, clés étrangères
-
idéal pour des données cohérentes et liées :
- profils
- notes
- projets
- documents
Supabase génère automatiquement :
-
une API REST pour chaque table
-
une API GraphQL (optionnelle)
-
une console web pour :
- gérer données
- configurer permissions
- voir les logs
2.6.4 Supabase – Authentification & permissions
Supabase propose un système d’auth complet :
- Email / mot de passe
- OAuth (Google, GitHub, etc.)
- Magic links
Les règles de sécurité sont basées sur Row Level Security (RLS) :
Les RLS permettent de définir qui peut lire / écrire quelle ligne dans une table, en fonction :
- de l’utilisateur connecté
- de son rôle
- du contexte (
auth.uid()…)
2.6.4 Supabase – Stockage de fichiers
Supabase inclut un service de stockage de fichiers :
- images
- vidéos
- autres médias
Organisation en buckets (comme Amazon S3).
L’accès aux fichiers suit :
- les mêmes logiques de permissions
- que la base de données (policies, RLS, etc.)
2.6.4 Supabase – Temps réel & Edge Functions
Supabase intègre :
-
un système realtime (basé sur PostgreSQL) :
- écoute des insertions / mises à jour / suppressions
-
des Edge Functions (fonctions serverless) pour :
- envoyer des emails
- traiter des images
- appliquer de la logique côté serveur
Permet de créer des interactions dynamiques dans l’app mobile.
2.6.4 Supabase – Pourquoi c’est pertinent en cours
L’approche SQL permet d’apprendre :
- les bases du backend sans gérer de serveur
- le langage SQL
- le lien API ↔ base de données
- les systèmes d’authentification modernes
- la sécurité (RLS, JWT, permissions)
- la synchronisation cloud pour mobile
2.6.4 Supabase – Exemple d’insertion
const { data, error } = await supabase
.from('notes')
.insert([
{ user_id: '214', title: 'Note de cours', content: 'Contenu de la note' }
])
🎯 Une seule instruction côté client → Supabase gère l’auth, la permission, l’écriture en base, et le retour JSON.
🔥 2.6.5 Firebase – solution NoSQL simple & temps réel
Firebase = plateforme BaaS de Google.
Points forts :
- intégration rapide
- SDK très simples
- synchronisation temps réel multi-appareils
2.6.5 Firebase – Stockage NoSQL
Deux systèmes principaux :
- Firestore → collections & documents
- Realtime Database → noeuds JSON synchronisés en direct
Ce modèle NoSQL est :
-
très flexible
-
sans relations strictes (comme en SQL)
-
performant pour :
- chat
- présence en ligne
- collaboration temps réel
2.6.5 Firebase – Temps réel
Lorsque des données changent :
- tous les clients abonnés reçoivent la mise à jour
- en quelques millisecondes
Idéal pour :
- messageries
- outils collaboratifs
- interfaces interactives en direct
2.6.5 Firebase – Auth intégrée
Firebase propose :
- email / mot de passe
- téléphone (SMS OTP)
- comptes Google, Apple, GitHub, etc.
Sessions :
- gérées automatiquement par les SDK
- persistance simplifiée
2.6.5 Firebase – Stockage de fichiers
Firebase propose :
- Cloud Storage pour images, vidéos, docs
- règles de sécurité liées au module Auth
🎯 Très pratique pour des apps simples qui doivent stocker des médias utilisateur.
2.6.5 Firebase – Quand le choisir ?
Firebase est particulièrement adapté :
- aux projets éducatifs
- aux prototypes rapides
- aux apps collaboratives / temps réel
- aux équipes cherchant une solution très simple à intégrer
2.6.5 Firebase – Points d’attention
Le NoSQL nécessite :
-
un modèle de données réfléchi
-
éviter :
- duplications abusives
- requêtes complexes difficiles à maintenir
- coûts surprises (lecture / écriture répétées)
💬 Firebase convient mieux aux données peu structurées ou très dynamiques.
⚖️ 2.6.6 Supabase vs Firebase
Deux approches :
- Supabase → SQL, standards ouverts
- Firebase → NoSQL, simplicité, temps réel
Les deux offrent :
- Auth
- Storage
- Fonctions serverless
- Realtime
Mais la philosophie est différente.
2.6.6 Supabase vs Firebase – Philosophies
-
Supabase → structure relationnelle, claire, avec contraintes → idéal pour applications avec modèle de données structuré
-
Firebase → documents & collections, très flexible → idéal pour données désynchronisées, temps réel
2.6.6 Tableau comparatif
| Critère | Supabase | Firebase |
|---|---|---|
| Type de base | Relationnelle (PostgreSQL) | NoSQL (Firestore) – Documents / Collections |
| API | REST + GraphQL natifs | SDK propriétaires uniquement |
| Auth | JWT, flexible (Email, OAuth, Magic Links) | Auth Google (simple / robuste), Email, téléphone, social |
| Realtime | Oui | Oui (très optimisé) |
| Storage | Buckets type S3 | Cloud Storage |
| Open-source | Oui | Non |
| Facile pour débutants | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Pertinence pédagogique | ⭐⭐⭐⭐⭐ (concepts universels) | ⭐⭐ (NoSQL uniquement) |
| Idéal pour… | projets structurés, SQL | prototypes, apps temps réel |
💬 En résumé
- Firebase : parfait pour démarrer vite, temps réel, concepts NoSQL.
- Supabase : idéal pour apprendre SQL + API REST + sécurité.
💭 2.6.7 Autres solutions BaaS populaires
☁️ Appwrite
- BaaS open-source
- Base NoSQL
- Auth complète
- Stockage de fichiers
- Fonctions serverless
- Interface d’admin web
✅ Souvent auto-hébergé → contrôle total des données.
2.6.7 AWS Amplify
Solution BaaS d’AWS :
- Base : DynamoDB
- Auth : Cognito
- Storage : S3
- Fonctions : Lambda
-
- outils de déploiement
⚠️ Puissant mais parfois complexe pour un débutant. Idéal pour projets à forte scalabilité dans l’écosystème AWS.
2.6.7 Backendless
Backendless propose :
- base de données relationnelle
- authentification
- stockage de fichiers
- fonctions serverless
- notifications push
Atouts :
- interface graphique conviviale
- nombreuses options de personnalisation
🎯 Adapté à ceux qui veulent une solution complète avec UI d’admin riche.
2.6.7 Back4app
Back4app (basé sur Parse Server) propose :
- base NoSQL
- authentification
- stockage de fichiers
- fonctions serverless
- notifications push
Atouts :
- simplicité d’utilisation
- modèle de tarification flexible
🎯 Intéressant si vous aimez l’approche Parse et une doc accessible.
🔄️ 2.6.8 Synchronisation cloud ↔ local
La synchronisation entre :
- stockage local (chapitre 2.4)
- backend cloud (chapitre 2.6)
est centrale pour une app mobile moderne.
🎯 Objectif : Offrir une expérience fluide, continue, fiable, même avec un réseau instable.
2.6.8 Pourquoi synchroniser ?
Parce que les données doivent être :
- accessibles hors ligne
- sauvegardées sur un serveur
- partageables entre plusieurs appareils
- aussi à jour que possible
Exemple : une app de notes avec sync entre smartphone, tablette et web.
2.6.8 Exemple – App de notes
-
L’app utilise SQLite pour enregistrer une note hors-ligne
-
Lorsque la connexion revient :
- la note est envoyée vers Supabase / Firebase
- la base cloud se met à jour
- les autres appareils peuvent récupérer la nouvelle note
2.6.8 Workflow standard de synchro
- Lecture initiale depuis le stockage local
- Mise à jour silencieuse depuis le cloud
- Queue locale d’actions hors-ligne
- Synchronisation automatique quand le réseau revient
- Gestion des conflits (local vs cloud)
2.6.8 Étape 1 – Lecture initiale (local)
Au démarrage :
- l’app charge immédiatement les données locales
- l’interface est utilisable sans réseau
- pas besoin d’appeler le cloud pour afficher quelque chose
// Lecture depuis SQLite au démarrage
const notes = await db.selectFrom('notes').selectAll().execute()
store.notes = notes
✅ Ouverture instantanée + fonctionnement offline garanti.
2.6.8 Étape 2 – Mise à jour silencieuse (cloud)
Si le réseau est disponible :
- l’app récupère les données du backend (Supabase, Firebase…)
- compare local / distant
- met à jour la base locale en arrière-plan
const { data } = await supabase
.from('notes')
.select('*')
.eq('user_id', user.id)
await saveToLocalDB(data)
💡 L’UI reste fluide → les nouvelles données remplacent progressivement l’ancien cache.
2.6.8 Étape 3 – File d’attente offline (queue)
Quand l’utilisateur agit sans réseau :
- crée une note
- modifie une tâche
- supprime un élément
L’app :
- met à jour les données en local
- ajoute l’action dans une queue locale
type PendingAction = {
id: string
type: 'CREATE_NOTE' | 'UPDATE_NOTE' | 'DELETE_NOTE'
payload: any
timestamp: number
}
🧠 La queue mémorise “ce que l’utilisateur voulait faire”.
2.6.8 Étape 4 – Sync automatique au retour du réseau
Avec Capacitor (Ionic) :
import { Network } from '@capacitor/network'
Network.addListener('networkStatusChange', status => {
if (status.connected) {
syncPendingActions()
}
})
Fonction de synchronisation :
async function syncPendingActions() {
for (const action of queue) {
await sendToBackend(action)
markActionSynced(action.id)
}
}
💡 Synchronisation automatique et silencieuse.
2.6.8 Étape 5 – Gestion des conflits
Conflit = même donnée modifiée :
- en local hors-ligne
- et sur le cloud, par un autre appareil
Stratégies :
- Last Write Wins (le plus récent gagne)
- Serveur prioritaire
- Local prioritaire (cas d’un brouillon)
- Merge logique (textes, documents collaboratifs)
2.6.8 Exemple de résolution simplifiée
if (local.updated_at > remote.updated_at) {
// garder la version locale
upload(local)
} else {
// garder la version cloud
saveToLocalDB(remote)
}
🧩 Le choix dépend du type d’application (notes, todo, documents, finances, etc.).
2.6.8 Bonus – Comment Ionic-Vue détecte la connectivité
Une app offline-first ne “poll” pas le réseau.
Avec Ionic-Vue + Capacitor Network :
- état réseau au démarrage
- événements envoyés par l’OS (online / offline)
🎯 L’app réagit aux changements de réseau, elle ne les surveille pas en boucle.
2.6.8 Détection au démarrage
import { Network } from '@capacitor/network'
const status = await Network.getStatus()
console.log('Connected at startup:', status.connected)
if (!status.connected) {
enterOfflineMode()
}
Exemple de sortie :
{
"connected": false,
"connectionType": "none"
}
L’app sait tout de suite si elle doit charger :
- uniquement les données locales (offline)
- ou lancer une synchronisation cloud
2.6.8 Événements réseau
iOS / Android envoient des événements :
- “offline”
- “Wi-Fi connecté”
- “4G/5G active”
- “réseau revenu”
import { Network } from '@capacitor/network'
Network.addListener('networkStatusChange', status => {
console.log('Network changed:', status)
if (status.connected) {
syncPendingActions()
} else {
enterOfflineMode()
}
})
C’est l’OS qui prévient l’app, pas l’inverse.
2.6.8 Gestion de la queue offline (rappel)
type PendingAction = {
id: string
type: 'CREATE' | 'UPDATE' | 'DELETE'
payload: any
timestamp: number
}
let queue: PendingAction[] = []
export function addOfflineAction(action: PendingAction) {
queue.push(action)
// TODO : sauvegarder en SQLite ou Capacitor Preferences
}
Puis :
// Exemple lorsqu’une note est éditée hors-ligne
addOfflineAction({
id: crypto.randomUUID(),
type: 'UPDATE',
payload: { id: 42, title: 'Nouvelle valeur' },
timestamp: Date.now()
})
L’UI se met à jour immédiatement → la sync viendra plus tard.
2.6.8 Sync quand le réseau revient (rappel)
async function syncPendingActions() {
for (const action of queue) {
await sendToBackend(action) // requête API
action.synced = true
}
// Nettoyage de la queue
queue = queue.filter(a => !a.synced)
}
✅ L’utilisateur ne fait rien. La synchronisation est automatique et fiable.
2.6.8 Résumé – Offline-first et BaaS
-
L’app récupère l’état réseau initial
-
L’OS signale les changements (online / offline)
-
Les actions offline vont dans une queue
-
Quand le réseau revient :
- les actions sont rejouées
- la queue est nettoyée
- le cloud et le local sont resynchronisés
🎯 Modèle utilisé par : WhatsApp, Notion, Google Drive, etc.
🔗 2.6.10 Références et ressources
-
Documentation Supabase https://supabase.com/docs
-
Guides Supabase – Auth, Database, Storage https://supabase.com/docs/guides
-
API REST Supabase (PostgREST) https://supabase.com/docs/guides/api/rest
-
Documentation Firebase https://firebase.google.com/docs
-
Firestore – Data Modeling Guide https://firebase.google.com/docs/firestore/data-model
-
Firebase Authentication https://firebase.google.com/docs/auth
-
Appwrite Documentation https://appwrite.io/docs
-
AWS Amplify Documentation https://docs.amplify.aws/
-
PostgreSQL Documentation https://www.postgresql.org/docs/
-
Understanding JSON Web Tokens (JWT.io) https://jwt.io
-
Offline-first Architecture Principles https://offlinefirst.org
-
MDN – REST API Concepts https://developer.mozilla.org/docs/Glossary/REST
☁️ 2.6 Persistance cloud et Backend-as-a-Service (BaaS)
By tirtho
☁️ 2.6 Persistance cloud et Backend-as-a-Service (BaaS)
- 26