9️⃣.1️⃣ Installation et configuration de SQLite
Pour stocker les données métier (les cartes) de manière durable et hors-ligne, nous allons utiliser SQLite.
Nous allons utiliser le plugin communautaire officiel : @capacitor-community/sqlite.
💬 Sur le web, SQLite est simulé à l'aide d'IndexedDB. Le comportement reste identique du point de vue de l'application.
9️⃣.1️⃣.1️⃣ Installation du plugin SQLite
Dans le terminal :
npm install @capacitor-community/sqliteNE PAS FAIRE 9️⃣.1️⃣.2️⃣ Configuration spécifique pour le navigateur (Web)
Sur Android et iOS, SQLite est fourni nativement par le système.
Sur le navigateur, en revanche, SQLite n’existe pas directement. Le plugin utilise donc :
- un Web Component (
jeep-sqlite), - et stocke les données dans IndexedDB.
Pour que SQLite fonctionne dans le navigateur (ionic serve), un Web Component est nécessaire.
Installez le loader web :
npm install jeep-sqliteEnsuite, enregistrez le composant jeep-sqlite dans src/main.ts :
import {createApp} from 'vue'
import App from './App.vue'
import router from './router';
import {IonicVue} from '@ionic/vue';
import {createPinia} from 'pinia';
import {useAuthStore} from '@/stores/authStore';
import {useNetworkStore} from '@/stores/networkStore';
import { defineCustomElements as jeepSqlite } from 'jeep-sqlite/loader'Puis, avant de créer l'application Vue (app.mount(...)), ajoutez le code suivant pour enregistrer le composant :
// ...
const pinia = createPinia()
app.use(pinia)
// Initialisation réseau
const networkStore = useNetworkStore(pinia)
networkStore.init()
// Initialisation auth
const authStore = useAuthStore(pinia)
authStore.init()
// 🔹 SQLite Web (IndexedDB)
jeepSqlite(window)
router.isReady().then(() => {
app.mount('#app')
})Pour que SQLite fonctionne réellement dans le navigateur, le composant jeep-sqlite doit être inséré dans le DOM. Dans le fichier index.html, ajoutez la ligne suivante juste avant la balise fermante </body> :
<!-- ... -->
<body>
<div id="app"></div>
<jeep-sqlite></jeep-sqlite> <!-- 🔹 SQLite Web (IndexedDB) -->
</body>👉 Sans cette étape, SQLite ne fonctionnera pas dans le navigateur.
9️⃣.1️⃣.3️⃣ Principe d'initialisation de SQLite
Avant d'utiliser SQLite, il faut :
- ouvrir une base locale,
- créer les tables si elles n'existent pas encore,
- garder une référence à la base.
Nous allons créer un service dédié, afin de centraliser cette logique. Ceci permettra de ne pas polluer les stores, réutiliser le code facilement et séparer la logique métier de la persistance des données.
9️⃣.1️⃣.4️⃣ Préparer Supabase pour la synchronisation
Avant d’implémenter la synchronisation offline ↔ online, il est indispensable que la base de données cloud soit prête à gérer des conflits et des comparaisons de versions.
👉 Pour cela, chaque carte doit disposer d’un champ
updated_atfiable côté Supabase.
Ce champ nous permettra :
- de comparer une version locale et une version cloud ;
- de décider laquelle est la plus récente ;
- d’appliquer notre règle métier (dans notre cas : local prioritaire).
1. Ajouter le champ updated_at dans Supabase
Dans le SQL Editor de Supabase, exécutez la requête suivante pour ajouter le champ updated_at dans la table cards :
ALTER TABLE public.cards
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
TIMESTAMPTZest le type de données pour une date/heure avec fuseau horaire.DEFAULT now()garantit que toute nouvelle carte aura toujours unupdated_at, même si le front ne l’envoie pas.
2. Initialiser updated_at pour les cartes existantes
Si des cartes existent déjà, leur champ updated_at est actuellement NULL. On va donc les initialiser avec la date de création created_at :
UPDATE public.cards
SET updated_at = created_at
WHERE updated_at IS NULL;3. Mettre à jour automatiquement updated_at lors des modifications
Lorsqu'une carte est modifiée (UPDATE), on veut que updated_at reflète automatiquement la date de la dernière modification.
Pour cela, on crée une fonction SQL et un trigger associé :
-- Fonction pour mettre à jour updated_at
CREATE OR REPLACE FUNCTION public.set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Trigger pour appeler la fonction avant chaque UPDATE
DROP TRIGGER IF EXISTS set_cards_updated_at ON public.cards;
CREATE TRIGGER set_cards_updated_at
BEFORE UPDATE ON public.cards
FOR EACH ROW
EXECUTE PROCEDURE public.set_updated_at();À chaque
UPDATEsur la tablecards, le trigger mettra automatiquement à jour le champupdated_atavec la date/heure actuelle.
🔜 La suite...
Dans la section suivante, nous allons :
- créer un service
sqliteService.ts, - initialiser la base locale,
- créer la table
cards, - préparer les méthodes CRUD locales.
