Connecter l'application à Supabase
Installer le client Supabase, ranger l'adresse et la clé du projet dans un fichier d'environnement, puis lire un premier résultat dans la base.
Objectifs de la séance
- installer
@supabase/supabase-jsetexpo-sqliteavecnpx expo install; - ranger l'URL et la clé publishable dans
.env.local(fichier jamais publié) et dans.env.example; - créer le client Supabase unique de l'application dans
src/lib/supabase.ts; - lire les thèmes dans un
useEffectet afficher le résultat sur l'accueil ; - terminer le tutoriel par une Pull Request et la fusion de la branche dans
main.
Petite vérification
Avant de commencer, vérifiez si vous savez...
- avec
curlet la clé publishable, lire la liste des thèmes de votre projet et compter les thèmes obtenus - avec
curl, tenter d'ajouter un thèmepirateet lire le code d'erreur renvoyé - dans le script
03_rls_lecture.sql, retrouver la condition de la policy qui masque les questions désactivées
📌 Réponse attendue
TP pour réfléchir et résoudre des problèmes
Votre mission : permettre à l'application de parler à votre base. Pour vérifier que cela
fonctionne, l'écran d'accueil affichera le message « Base de données connectée : 3 thèmes. ».
Arrêtez le serveur Expo (Ctrl + C) avant l'étape 1.
Étape 1 — Installer les bibliothèques
npx expo install installe les versions compatibles avec votre SDK Expo (contrairement à
npm install, qui prend la dernière version disponible) :
Ouvrez ensuite app.json et vérifiez que "expo-sqlite" figure dans la liste plugins (sinon, ajoutez-le à la fin de la liste) :
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"backgroundColor": "#208AEF",
"image": "./assets/images/splash-icon.png",
"imageWidth": 76
}
],
"expo-sqlite"
],
Les bibliothèques d'une application mobile dépendent fortement de la version d'Expo. npx expo install
choisit la bonne version pour chacune : c'est la commande à utiliser pour tout paquet destiné à
l'application.
Étape 2 — Ranger l'URL et la clé dans des variables d'environnement
Créez à la racine du projet deux fichiers :
.env.example: un modèle, avec de fausses valeurs, qui sera versionné ;.env.local: vos vraies valeurs, qui ne seront jamais publiées (le.gitignoredu projet ignore les fichiers.env*.local).
Dans .env.local, mettez l'URL (Project Settings > Data API) et la clé publishable
(Project Settings > API Keys) de votre projet :
EXPO_PUBLIC_SUPABASE_URL=https://VOTRE_PROJET.supabase.co
EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_VOTRE_CLE
Le fichier .env.example explique, lui, comment s'en servir. Complétez sa dernière ligne :
Tapez maintenant git status : le fichier .env.example doit apparaître comme nouveau, mais
pas .env.local. S'il apparaît, arrêtez-vous et appelez votre enseignant.
.env.example permet à un coéquipier de savoir quelles variables créer sans jamais voir vos vraies
valeurs. Dans les entreprises, c'est une pratique standard.
Étape 3 — Lire les variables dans le code
Créez le dossier src/lib et le fichier src/lib/supabase.ts. Ce fichier crée le client
Supabase, l'objet qui permet d'envoyer des requêtes à la base. Il est créé une seule fois pour
toute l'application. Commencez par lire les deux variables :
Sans le if, un fichier .env.local oublié provoquerait une erreur obscure plus tard, au premier
appel réseau. Avec lui, l'application s'arrête immédiatement en disant quoi vérifier.
Étape 4 — Créer le client Supabase
Terminez le fichier : le client est créé avec createClient, en lui donnant l'URL, la clé, et des
options pour mémoriser la session de l'utilisateur (utile à partir du tutoriel 8). Les pages Web
peuvent aussi être pré-calculées dans Node.js (lors du rendu serveur), où il n'existe pas de navigateur :
on le détecte pour ne rien mémoriser dans ce cas.
Créer le client dans un fichier à part, exporté une seule fois, évite d'en ouvrir plusieurs (ce qui
multiplierait les sessions et les connexions). Tous les autres fichiers l'importent avec
import { supabase } from "@/lib/supabase".
Étape 5 — Lire les thèmes sur l'écran d'accueil
Pour vérifier la connexion, l'écran d'accueil lit les thèmes dans la base et affiche leur nombre.
La lecture se fait dans un useEffect, avec un drapeau d'annulation estAnnule : si l'écran
disparaît avant que la réponse n'arrive, on ne met plus l'état à jour.
Dans src/app/index.tsx, ajoutez l'import de supabase, un état messageConnexion, et ce useEffect
(placez-le avant le return) :
Ajoutez aussi, sous le texte de présentation, l'affichage du message
(<Text style={styles.info}>{messageConnexion}</Text>) et le style info correspondant (voir la
solution). Puis redémarrez le serveur : npx expo start, touche w.
Les variables EXPO_PUBLIC_... sont lues au démarrage du serveur. Si vous modifiez .env.local, arrêtez
le serveur (Ctrl + C) puis relancez npx expo start, sinon l'application utilise les anciennes valeurs.
Vous devez lire « Base de données connectée : 3 thèmes. ». Testez ensuite l'échec : dans les outils
du navigateur (F12, onglet Réseau), passez en mode Hors connexion puis rechargez la page : le
message devient « Base de données injoignable. ».
Une requête Supabase ne déclenche pas d'exception : elle renvoie un objet { data, error }. Il faut
toujours tester error avant d'utiliser data, sinon on lit un résultat qui n'existe pas.
Étape 6 — Enregistrer votre travail
Avant git commit, git status doit montrer .env.example mais jamais .env.local. Une clé
publiée par erreur reste visible dans l'historique, même supprimée ensuite.
Étape 7 — Fusionner la branche dans main
Le tutoriel est terminé : la branche feature/supabase peut rejoindre main.
- Sur GitHub, ouvrez votre dépôt : un bandeau propose Compare & pull request pour la branche
feature/supabase. Cliquez dessus. - Donnez un titre clair à la Pull Request (par exemple « Base de données Supabase et connexion ») et relisez les fichiers modifiés dans l'onglet Files changed : il ne doit y avoir aucune clé.
- Cliquez sur Create pull request, puis sur Merge pull request et Confirm merge.
- Revenez dans le terminal pour mettre à jour votre dépôt local et supprimer la branche devenue inutile.
L'onglet Files changed est la dernière occasion de repérer un fichier ou une clé qui n'a rien à faire là. En entreprise, un collègue relit aussi cette page avant d'autoriser la fusion.
📌 Une solution
Notions théoriques
Le client Supabase
La bibliothèque @supabase/supabase-js fournit un client : un objet supabase qui sait envoyer des
requêtes à l'API de votre projet. Sa syntaxe ressemble à une phrase :
const { data, error } = await supabase.from("theme").select("code");
from("theme"): la table visée ;select("code"): les colonnes demandées ;await: on attend la réponse du serveur (la requête passe par le réseau) ;- le résultat est toujours un objet
{ data, error }: en cas de problème,errorest rempli etdataest vide.
Le client applique les droits de la clé publishable : il ne voit que ce que les policies RLS autorisent. C'est la raison pour laquelle vous les avez écrites avant de brancher l'application.
Les variables d'environnement
Une variable d'environnement est une valeur de configuration qui n'est pas écrite dans le code. Avec Expo :
- les variables commencent par
EXPO_PUBLIC_; seules celles-ci sont accessibles dans le code ; - elles sont lues dans le fichier
.env.localet recopiées dans le code au moment de la compilation ; - on les lit avec
process.env.EXPO_PUBLIC_NOM, toujours écrit avec un point (une écriture dynamique commeprocess.env[nom]ne fonctionne pas).
Tout ce qui commence par EXPO_PUBLIC_ finit dans le code livré à l'utilisateur : n'importe qui peut
le lire. C'est acceptable pour l'URL et la clé publishable. Ce serait une faille majeure pour une
clé secret ou service_role : ne les mettez jamais dans une variable EXPO_PUBLIC_.
Fichiers .env.local et .env.example
| Fichier | Contenu | Versionné ? |
|---|---|---|
.env.local | vos vraies valeurs | non (ignoré par .gitignore) |
.env.example | les noms des variables, avec de fausses valeurs | oui |
Le rendu serveur du Web
Pour la version Web, Expo peut pré-calculer les pages dans Node.js avant de les envoyer au
navigateur. Dans Node.js, il n'y a ni window ni localStorage : le client Supabase ne doit donc pas
essayer de mémoriser de session dans ce cas, d'où la constante estRenduServeur.
Lire dans un useEffect avec un drapeau d'annulation
Une lecture réseau est asynchrone : la réponse arrive plus tard, et l'écran a peut-être disparu
entre-temps. Mettre à jour l'état d'un composant qui n'existe plus est une erreur. Le drapeau
estAnnule règle ce problème : la fonction de nettoyage du useEffect le passe à true quand
l'écran disparaît, et le code vérifie ce drapeau avant chaque setState.
Ce n'est qu'une première protection. Au tutoriel suivant, vous apprendrez à vraiment annuler la requête, à afficher un état de chargement et un état d'erreur, et à éviter que des réponses arrivent dans le désordre.
Test de mémorisation/compréhension
Exercices complémentaires
Exercice A : provoquer une erreur de configuration
Renommez temporairement la variable EXPO_PUBLIC_SUPABASE_URL en EXPO_PUBLIC_SUPABASE_URL2 dans
.env.local, redémarrez le serveur et lisez le message d'erreur affiché. Puis remettez le bon nom.
Exercice B : afficher les libellés
Au lieu de select("code"), lisez la colonne libelle (select("libelle")) et affichez le premier
libellé reçu (data[0].libelle) dans le message de l'accueil. Remettez ensuite le code d'origine.
Ce qu'il faut retenir
| Notion | Résumé |
|---|---|
npx expo install | Installe la version d'une bibliothèque compatible avec le SDK Expo. |
| Client Supabase | Objet supabase créé une seule fois dans src/lib/supabase.ts. |
EXPO_PUBLIC_ | Préfixe des variables lisibles dans le code ; tout ce qui l'a est public. |
.env.local / .env.example | Vraies valeurs (ignorées par Git) et modèle (versionné). |
| Clé secret | Jamais dans l'application : elle contournerait toute la sécurité de la base. |
{ data, error } | Résultat d'une requête Supabase : toujours tester error avant data. |
| Pull Request | Fusionne la branche du tutoriel dans main, après relecture des fichiers modifiés. |
Aperçu de la prochaine séance
Votre application lit enfin des données en ligne ! Mais le code de l'accueil est fragile : que se passe-t-il quand le réseau est lent, ou coupé ? Dans le tutoriel suivant, vous allez rendre l'application robuste : un indicateur de chargement, un message d'erreur avec un bouton « Réessayer », l'annulation des requêtes devenues inutiles, et les thèmes du générateur chargés depuis la base.