Flutter Templates
Créer une application de réseau social avec Flutter et Back4App
54 min
introduction créer une application de réseau social peut être une tâche complexe, mais avec flutter et back4app, vous pouvez simplifier le processus de développement ce tutoriel vous guidera à travers la création d'une application de réseau social complète qui inclut l'authentification des utilisateurs, la gestion des profils, les fils d'actualités, les connexions d'amis, la messagerie et les notifications à la fin de ce tutoriel, vous aurez une application de réseau social fonctionnelle avec les fonctionnalités suivantes authentification des utilisateurs processus d'inscription et de connexion sécurisés profils d'utilisateurs profils modifiables avec des informations sur l'utilisateur fils d'actualités afficher les publications des amis et de l'utilisateur connexions d'amis possibilité d'envoyer et d'accepter des demandes d'amis messagerie chat en temps réel entre les utilisateurs notifications notifications push pour les demandes d'amis, les messages et les interactions sur les publications prérequis pour suivre ce tutoriel, vous aurez besoin de flutter sdk installé sur votre machine suivez le guide d'installation officiel de flutter https //flutter dev/docs/get started/install pour votre système d'exploitation connaissances de base en flutter et dart si vous êtes nouveau dans flutter, consultez la documentation flutter https //flutter dev/docs pour vous familiariser avec les bases un ide ou éditeur de texte tel que visual studio code ou android studio un compte back4app inscrivez vous pour un compte gratuit sur back4app https //www back4app com/ parse server sdk pour flutter ajouté à votre projet apprenez à le configurer en suivant le guide back4app flutter sdk https //www back4app com/docs/flutter/parse flutter sdk étape 1 – configuration du projet flutter 1 1 créer un nouveau projet flutter ouvrez votre terminal et exécutez flutter create social app accédez au répertoire du projet cd social app 1 2 ajouter des dépendances ouvrez pubspec yaml et ajoutez les dépendances suivantes dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 provider ^6 0 0 image picker ^0 8 4+6 cached network image ^3 2 0 firebase messaging ^11 2 8 uuid ^3 0 6 exécutez flutter pub get pour installer les paquets remarque nous utilisons parse server sdk flutter pour l'intégration back4app provider pour la gestion d'état image picker pour sélectionner des images de profil et de publication cached network image pour un chargement d'images efficace firebase messaging pour les notifications push uuid pour générer des identifiants uniques étape 2 – configuration de back4app 2 1 créer une nouvelle application back4app connectez vous à votre tableau de bord back4app https //dashboard back4app com/ cliquez sur "créer une nouvelle application" entrez un nom pour votre application, par exemple, "socialapp" , et cliquez sur "créer" 2 2 configurer les modèles de données nous devrons créer plusieurs classes dans back4app utilisateur classe intégrée pour l'authentification des utilisateurs profil stocke les informations de profil de l'utilisateur publication stocke les publications des utilisateurs demande d'ami gère les demandes d'amis entre les utilisateurs message stocke les messages entre les utilisateurs 2 2 1 classe de profil naviguez vers la "base de données" section cliquez sur "créer une classe" dans la modal sélectionnez "personnalisé" entrez "profil" comme nom de classe cliquez sur "créer une classe" ajoutez les colonnes suivantes utilisateur type pointer< user> nom d'utilisateur type string nomcomplet type string bio type string photodeprofil type fichier 2 2 2 classe de post créer un "post" classe avec les colonnes suivantes utilisateur type pointer< user> contenu type string image type file crééà type date 2 2 3 classe friendrequest créer un "friendrequest" classe avec les colonnes suivantes deutilisateur type pointer< user> àutilisateur type pointer< user> statut type string (valeurs "en attente", "accepté", "rejeté") 2 2 4 classe message créer un "message" classe avec les colonnes suivantes deutilisateur type pointer< user> àutilisateur type pointer< user> contenu type string crééà type date 2 3 obtenir les identifiants de l'application naviguer vers paramètres de l'application > sécurité et clés notez votre id d'application et clé client étape 3 – initialisation de parse dans votre application flutter ouvrez lib/main dart et modifiez le comme suit import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import 'services/auth service dart'; import 'screens/login screen dart'; void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, ); runapp(myapp()); } class myapp extends statelesswidget { @override widget build(buildcontext context) { return changenotifierprovider\<authservice>( create ( ) => authservice(), child materialapp( title 'social app', theme themedata( primaryswatch colors blue, ), home loginscreen(), ), ); } } remplacez 'your application id' et 'your client key' par vos identifiants back4app nous utilisons changenotifierprovider pour gérer l'état d'authentification étape 4 – mise en œuvre de l'authentification des utilisateurs 4 1 créer le service d'authentification créez un nouveau répertoire appelé services sous lib et ajoutez un fichier nommé auth service dart // lib/services/auth service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class authservice with changenotifier { parseuser? user; future\<bool> signup(string username, string password, string email) async { user = parseuser createuser(username, password, email); final response = await user! signup(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<bool> login(string username, string password) async { user = parseuser(username, password, null); final response = await user! login(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<void> logout() async { if (user != null) { await user! logout(); user = null; notifylisteners(); } } bool get isauthenticated => user != null; } 4 2 créer les écrans de connexion et d'inscription créez un répertoire appelé screens sous lib et ajoutez login screen dart et signup screen dart 4 2 1 écran de connexion // lib/screens/login screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'signup screen dart'; import 'home screen dart'; class loginscreen extends statefulwidget { @override loginscreenstate createstate() => loginscreenstate(); } class loginscreenstate extends state\<loginscreen> { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void login() async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice login( usernamecontroller text trim(), passwordcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder (context) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('login failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('social app login'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton(onpressed login, child text('login')), textbutton( onpressed () { navigator push( context, materialpageroute(builder ( ) => signupscreen()), ); }, child text('don\\'t have an account? sign up'), ) ], ), ), ); } } 4 2 2 écran d’inscription // lib/screens/signup screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'home screen dart'; class signupscreen extends statefulwidget { @override signupscreenstate createstate() => signupscreenstate(); } class signupscreenstate extends state\<signupscreen> { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); final texteditingcontroller emailcontroller = texteditingcontroller(); void signup() async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice signup( usernamecontroller text trim(), passwordcontroller text trim(), emailcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder (context) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('signup failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('social app signup'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username'), ), textfield( controller emailcontroller, decoration inputdecoration(labeltext 'email'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton(onpressed signup, child text('sign up')), ], ), ), ); } } étape 5 – configuration des profils utilisateurs 5 1 créer le service de profil ajoutez un fichier nommé profile service dart sous lib/services/ // lib/services/profile service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/profile dart'; class profileservice { future\<void> createprofile(parseuser user) async { final profile = parseobject('profile') set('user', user) set('username', user username); await profile save(); } future\<profile?> getprofile(parseuser user) async { final query = querybuilder\<parseobject>(parseobject('profile')) whereequalto('user', user); final response = await query query(); if (response success && response results != null) { final profileobject = response results! first; return profile fromparseobject(profileobject); } else { return null; } } future\<void> updateprofile(profile profile) async { final profileobject = parseobject('profile') objectid = profile id set('fullname', profile fullname) set('bio', profile bio); await profileobject save(); } } 5 2 créer le modèle de profil ajoutez un fichier nommé profile dart sous lib/models/ // lib/models/profile dart import 'package\ parse server sdk flutter/parse server sdk dart'; class profile { string id; string username; string? fullname; string? bio; parsefilebase? profilepicture; profile({ required this id, required this username, this fullname, this bio, this profilepicture, }); factory profile fromparseobject(parseobject object) { return profile( id object objectid!, username object get\<string>('username')!, fullname object get\<string>('fullname'), bio object get\<string>('bio'), profilepicture object get\<parsefilebase>('profilepicture'), ); } } 5 3 créer l'écran de profil ajoutez un fichier nommé profile screen dart sous lib/screens/ // lib/screens/profile screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import ' /services/profile service dart'; import ' /models/profile dart'; class profilescreen extends statefulwidget { @override profilescreenstate createstate() => profilescreenstate(); } class profilescreenstate extends state\<profilescreen> { final profileservice profileservice = profileservice(); profile? profile; final texteditingcontroller fullnamecontroller = texteditingcontroller(); final texteditingcontroller biocontroller = texteditingcontroller(); void loadprofile() async { final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; profile? fetchedprofile = await profileservice getprofile(user); if (fetchedprofile == null) { await profileservice createprofile(user); fetchedprofile = await profileservice getprofile(user); } setstate(() { profile = fetchedprofile; fullnamecontroller text = profile? fullname ?? ''; biocontroller text = profile? bio ?? ''; }); } void saveprofile() async { if (profile != null) { profile! fullname = fullnamecontroller text trim(); profile! bio = biocontroller text trim(); await profileservice updateprofile(profile!); scaffoldmessenger of(context) showsnackbar(snackbar(content text('profile updated'))); } } @override void initstate() { super initstate(); loadprofile(); } @override widget build(buildcontext context) { if (profile == null) { return scaffold( appbar appbar(title text('profile')), body center(child circularprogressindicator()), ); } return scaffold( appbar appbar(title text(profile! username)), body padding( padding const edgeinsets all(16), child column( children \[ // add profile picture handling here textfield( controller fullnamecontroller, decoration inputdecoration(labeltext 'full name'), ), textfield( controller biocontroller, decoration inputdecoration(labeltext 'bio'), ), sizedbox(height 20), elevatedbutton(onpressed saveprofile, child text('save')), ], ), ), ); } } étape 6 – mise en œuvre des flux d'actualités 6 1 créer le service de publication ajoutez un fichier nommé post service dart sous lib/services/ // lib/services/post service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/post dart'; class postservice { future\<void> createpost(string content, parseuser user) async { final post = parseobject('post') set('user', user) set('content', content); await post save(); } future\<list\<post>> getposts(parseuser user) async { final query = querybuilder\<parseobject>(parseobject('post')) orderbydescending('createdat') includeobject(\['user']); final response = await query query(); if (response success && response results != null) { return response results! map((e) => post fromparseobject(e)) tolist(); } else { return \[]; } } } 6 2 créer le modèle de publication ajoutez un fichier nommé post dart sous lib/models/ // lib/models/post dart import 'package\ parse server sdk flutter/parse server sdk dart'; class post { string id; string content; parseuser user; datetime createdat; post({ required this id, required this content, required this user, required this createdat, }); factory post fromparseobject(parseobject object) { return post( id object objectid!, content object get\<string>('content')!, user object get\<parseuser>('user')!, createdat object createdat!, ); } } 6 3 créer l'écran d'accueil modifier home screen dart sous lib/screens/ // lib/screens/home screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import ' /services/post service dart'; import ' /models/post dart'; import 'profile screen dart'; class homescreen extends statefulwidget { @override homescreenstate createstate() => homescreenstate(); } class homescreenstate extends state\<homescreen> { final postservice postservice = postservice(); list\<post> posts = \[]; final texteditingcontroller postcontroller = texteditingcontroller(); void loadposts() async { final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; list\<post> fetchedposts = await postservice getposts(user); setstate(() { posts = fetchedposts; }); } void createpost() async { final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; await postservice createpost( postcontroller text trim(), user); postcontroller clear(); loadposts(); } @override void initstate() { super initstate(); loadposts(); } @override widget build(buildcontext context) { final authservice = provider of\<authservice>(context); return scaffold( appbar appbar( title text('social app'), actions \[ iconbutton( icon icon(icons person), onpressed () { navigator push( context, materialpageroute(builder ( ) => profilescreen()), ); }, ), iconbutton( icon icon(icons logout), onpressed () async { await authservice logout(); navigator pushreplacementnamed(context, '/'); }, ), ], ), body column( children \[ textfield( controller postcontroller, decoration inputdecoration( hinttext 'what\\'s on your mind?', contentpadding edgeinsets all(16), ), ), elevatedbutton(onpressed createpost, child text('post')), expanded( child listview\ builder( itemcount posts length, itembuilder (context, index) { final post = posts\[index]; return listtile( title text(post user username ?? 'unknown'), subtitle text(post content), trailing text( post createdat tolocal() tostring(), style textstyle(fontsize 12), ), ); }, ), ), ], ), ); } } étape 7 – ajout de connexions d'amis dans cette étape, nous allons mettre en œuvre des connexions d'amis entre les utilisateurs les utilisateurs peuvent envoyer des demandes d'amis, les accepter ou les rejeter, et consulter leur liste d'amis nous allons modifier les modèles de données, créer des services et mettre à jour l'interface utilisateur pour prendre en charge cette fonctionnalité 7 1 mettre à jour le modèle de données nous avons déjà créé la friendrequest classe dans back4app avec les colonnes suivantes fromuser pointeur vers user touser pointeur vers user status chaîne (valeurs "en attente", "accepté", "rejeté") de plus, nous devons suivre la liste d'amis d'un utilisateur nous pouvons le faire en ajoutant une relation dans la classe user 7 1 1 ajouter une relation d'amis à la classe utilisateur dans back4app, allez à la classe utilisateur cliquez sur le "+" bouton pour ajouter une nouvelle colonne nommez la colonne "amis" et définissez le type sur relation < user> 7 2 créer un service de demande d'amis créez un fichier nommé friend service dart sous lib/services/ // lib/services/friend service dart import 'package\ parse server sdk flutter/parse server sdk dart'; class friendservice { future\<bool> sendfriendrequest(parseuser fromuser, parseuser touser) async { final friendrequest = parseobject('friendrequest') set('fromuser', fromuser) set('touser', touser) set('status', 'pending'); final response = await friendrequest save(); return response success; } future\<list\<parseobject>> getpendingrequests(parseuser user) async { final query = querybuilder\<parseobject>(parseobject('friendrequest')) whereequalto('touser', user) whereequalto('status', 'pending') includeobject(\['fromuser']); final response = await query query(); if (response success && response results != null) { return response results!; } else { return \[]; } } future\<bool> acceptfriendrequest(parseobject friendrequest) async { friendrequest set('status', 'accepted'); final response = await friendrequest save(); if (response success) { // add each user to the other's friends relation final fromuser = friendrequest get\<parseuser>('fromuser')!; final touser = friendrequest get\<parseuser>('touser')!; fromuser setadd('friends', \[touser]); touser setadd('friends', \[fromuser]); await fromuser save(); await touser save(); return true; } return false; } future\<bool> rejectfriendrequest(parseobject friendrequest) async { friendrequest set('status', 'rejected'); final response = await friendrequest save(); return response success; } future\<list\<parseuser>> getfriends(parseuser user) async { final relation = user getrelation\<parseuser>('friends'); final query = relation query(); final response = await query query(); if (response success && response results != null) { return response results! cast\<parseuser>(); } else { return \[]; } } } 7 3 mettre à jour l'interface utilisateur 7 3 1 ajouter l'écran de recherche d'utilisateurs créez un fichier nommé search users screen dart sous lib/screens/ // lib/screens/search users screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import ' /services/friend service dart'; class searchusersscreen extends statefulwidget { @override searchusersscreenstate createstate() => searchusersscreenstate(); } class searchusersscreenstate extends state\<searchusersscreen> { final texteditingcontroller searchcontroller = texteditingcontroller(); list\<parseuser> users = \[]; final friendservice friendservice = friendservice(); void searchusers() async { final query = querybuilder\<parseuser>(parseuser forquery()) wherecontains('username', searchcontroller text trim()) wherenotequalto('objectid', provider of\<authservice>(context, listen false) user! objectid); final response = await query query(); if (response success && response results != null) { setstate(() { users = response results! cast\<parseuser>(); }); } else { setstate(() { users = \[]; }); } } void sendfriendrequest(parseuser touser) async { final fromuser = provider of\<authservice>(context, listen false) user!; bool success = await friendservice sendfriendrequest(fromuser, touser); if (success) { scaffoldmessenger of(context) showsnackbar(snackbar(content text('friend request sent'))); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('failed to send friend request'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('search users'), ), body column( children \[ padding( padding const edgeinsets all(16 0), child textfield( controller searchcontroller, decoration inputdecoration( hinttext 'search by username', suffixicon iconbutton( icon icon(icons search), onpressed searchusers, ), ), ), ), expanded( child listview\ builder( itemcount users length, itembuilder (context, index) { final user = users\[index]; return listtile( title text(user username ?? 'unknown'), trailing elevatedbutton( onpressed () => sendfriendrequest(user), child text('add friend'), ), ); }, ), ), ], ), ); } } 7 3 2 ajouter l'écran des demandes d'amis créez un fichier nommé friend requests screen dart sous lib/screens/ // lib/screens/friend requests screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import ' /services/friend service dart'; class friendrequestsscreen extends statefulwidget { @override friendrequestsscreenstate createstate() => friendrequestsscreenstate(); } class friendrequestsscreenstate extends state\<friendrequestsscreen> { final friendservice friendservice = friendservice(); list\<parseobject> friendrequests = \[]; void loadfriendrequests() async { final user = provider of\<authservice>(context, listen false) user!; final requests = await friendservice getpendingrequests(user); setstate(() { friendrequests = requests; }); } void acceptrequest(parseobject request) async { bool success = await friendservice acceptfriendrequest(request); if (success) { scaffoldmessenger of(context) showsnackbar(snackbar(content text('friend request accepted'))); loadfriendrequests(); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('failed to accept friend request'))); } } void rejectrequest(parseobject request) async { bool success = await friendservice rejectfriendrequest(request); if (success) { scaffoldmessenger of(context) showsnackbar(snackbar(content text('friend request rejected'))); loadfriendrequests(); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('failed to reject friend request'))); } } @override void initstate() { super initstate(); loadfriendrequests(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('friend requests'), ), body listview\ builder( itemcount friendrequests length, itembuilder (context, index) { final request = friendrequests\[index]; final fromuser = request get\<parseuser>('fromuser')!; return listtile( title text(fromuser username ?? 'unknown'), subtitle text('sent you a friend request'), trailing row( mainaxissize mainaxissize min, children \[ iconbutton( icon icon(icons check, color colors green), onpressed () => acceptrequest(request), ), iconbutton( icon icon(icons close, color colors red), onpressed () => rejectrequest(request), ), ], ), ); }, ), ); } } 7 3 3 mettre à jour la navigation de l'écran d'accueil dans home screen dart , ajoutez la navigation vers les écrans de recherche d'utilisateurs et de demandes d'amis // inside appbar actions iconbutton( icon icon(icons person add), onpressed () { navigator push( context, materialpageroute(builder ( ) => searchusersscreen()), ); }, ), iconbutton( icon icon(icons notifications), onpressed () { navigator push( context, materialpageroute(builder ( ) => friendrequestsscreen()), ); }, ), 7 4 mettre à jour le fil d'actualités pour afficher les publications des amis modifier le getposts méthode dans post service dart pour récupérer les publications de l'utilisateur et de ses amis // lib/services/post service dart future\<list\<post>> getposts(parseuser user) async { // get friends final relation = user getrelation\<parseuser>('friends'); final friendsquery = relation query(); final friendsresponse = await friendsquery query(); list\<string> userids = \[user objectid!]; if (friendsresponse success && friendsresponse results != null) { final friends = friendsresponse results! cast\<parseuser>(); userids addall(friends map((friend) => friend objectid!)); } // fetch posts from user and friends final query = querybuilder\<parseobject>(parseobject('post')) wherecontainedin('user', userids map((id) => parseuser(null, null, null) objectid = id) tolist()) orderbydescending('createdat') includeobject(\['user']); final response = await query query(); if (response success && response results != null) { return response results! map((e) => post fromparseobject(e)) tolist(); } else { return \[]; } } étape 8 – mise en œuvre de la messagerie dans cette étape, nous allons ajouter un messaging en temps réel entre les utilisateurs en utilisant les live queries 8 1 activer les live queries dans back4app dans le tableau de bord de votre application back4app, allez à app settings > server settings sous server url , notez votre url de serveur (par exemple, https //your app name back4app io ) les live queries sont activées par défaut sur back4app 8 2 configurer les live queries dans flutter le parse server sdk flutter package inclut le support des live queries 8 3 créer un service de messagerie créez un fichier nommé message service dart sous lib/services/ // lib/services/message service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/message dart'; class messageservice { parselivelist\<message>? livemessagelist; future\<void> sendmessage(parseuser fromuser, parseuser touser, string content) async { final message = parseobject('message') set('fromuser', fromuser) set('touser', touser) set('content', content); await message save(); } future\<void> subscribetomessages(parseuser user, parseuser otheruser, function(list\<message>) onmessagesupdated) async { final querybuilder = querybuilder\<parseobject>(parseobject('message')) whereequalto('fromuser', user) whereequalto('touser', otheruser) orderbyascending('createdat') includeobject(\['fromuser', 'touser']); livemessagelist = parselivelist\<message>(querybuilder, listenonallsubitems true); livemessagelist! stream listen((event) { onmessagesupdated(livemessagelist! items); }); } future\<void> dispose() async { await livemessagelist? dispose(); } } 8 4 créer un modèle de message ajoutez un fichier nommé message dart sous lib/models/ // lib/models/message dart import 'package\ parse server sdk flutter/parse server sdk dart'; class message extends parseobject implements parsecloneable { message() super('message'); message clone() this(); @override clone(map\<string, dynamic> map) => message clone() fromjson(map); parseuser get fromuser => get\<parseuser>('fromuser')!; parseuser get touser => get\<parseuser>('touser')!; string get content => get\<string>('content')!; } 8 5 créer l'écran de chat ajoutez un fichier nommé chat screen dart sous lib/screens/ // lib/screens/chat screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import ' /models/message dart'; import ' /services/auth service dart'; import ' /services/message service dart'; class chatscreen extends statefulwidget { final parseuser otheruser; chatscreen({required this otheruser}); @override chatscreenstate createstate() => chatscreenstate(); } class chatscreenstate extends state\<chatscreen> { final messageservice messageservice = messageservice(); list\<message> messages = \[]; final texteditingcontroller messagecontroller = texteditingcontroller(); void sendmessage() { final authservice = provider of\<authservice>(context, listen false); final fromuser = authservice user!; final touser = widget otheruser; messageservice sendmessage(fromuser, touser, messagecontroller text trim()); messagecontroller clear(); } void onmessagesupdated(list\<message> updatedmessages) { setstate(() { messages = updatedmessages; }); } @override void initstate() { super initstate(); final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; messageservice subscribetomessages(user, widget otheruser, onmessagesupdated); } @override void dispose() { messageservice dispose(); super dispose(); } @override widget build(buildcontext context) { final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; return scaffold( appbar appbar(title text(widget otheruser username ?? 'chat')), body column( children \[ expanded( child listview( children messages map((message) { bool isme = message fromuser objectid == user objectid; return listtile( title align( alignment isme ? alignment centerright alignment centerleft, child container( padding edgeinsets all(10), color isme ? colors blueaccent colors grey\[300], child text( message content, style textstyle(color isme ? colors white colors black), ), ), ), ); }) tolist(), ), ), divider(height 1), container( padding edgeinsets symmetric(horizontal 8 0), color theme of(context) cardcolor, child row( children \[ flexible( child textfield( controller messagecontroller, decoration inputdecoration collapsed(hinttext 'send a message'), ), ), iconbutton( icon icon(icons send), onpressed sendmessage, ), ], ), ) ], ), ); } } 8 6 mettre à jour l'interface utilisateur pour initier le chat vous pouvez initier le chat depuis la liste d'amis ou l'écran de recherche d'utilisateurs dans la liste d'amis, lors de l'affichage des amis, ajoutez un bouton pour commencer un chat // inside the listtile for a friend trailing iconbutton( icon icon(icons chat), onpressed () { navigator push( context, materialpageroute(builder ( ) => chatscreen(otheruser friend)), ); }, ), étape 9 – ajout de notifications push la mise en œuvre des notifications push implique la configuration de firebase cloud messaging (fcm) et son intégration avec back4app 9 1 configurer firebase cloud messaging 9 1 1 configurer le projet firebase allez sur firebase console https //console firebase google com/ et créez un nouveau projet ajoutez une application android et/ou ios à votre projet pour android, vous avez besoin du nom du package (applicationid) pour ios, vous avez besoin de l'identifiant de bundle 9 1 2 télécharger les fichiers de configuration pour android téléchargez google services json et placez le dans android/app/ pour ios téléchargez googleservice info plist et ajoutez le à votre projet xcode sous runner 9 2 ajouter le package firebase messaging assurez vous d'avoir ajouté firebase messaging à votre pubspec yaml dependencies firebase messaging ^11 2 8 exécutez flutter pub get pour installer 9 3 initialiser firebase dans flutter modifier main dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ firebase core/firebase core dart'; // other imports void main() async { widgetsflutterbinding ensureinitialized(); await firebase initializeapp(); // initialize parse as before runapp(myapp()); } 9 4 configurer firebase messaging créer un fichier nommé push notification service dart sous lib/services/ // lib/services/push notification service dart import 'package\ firebase messaging/firebase messaging dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class pushnotificationservice { final firebasemessaging fcm = firebasemessaging instance; future\<void> init() async { // request permissions (ios) await fcm requestpermission(); // get the token string? token = await fcm gettoken(); if (token != null) { // save the token to parse installation final installation = await parseinstallation currentinstallation(); installation set('devicetoken', token); await installation save(); } // handle foreground messages firebasemessaging onmessage listen((remotemessage message) { print('received a message in the foreground!'); // handle the message }); } } 9 5 mettre à jour main dart pour initialiser les notifications push dans main dart , après avoir initialisé parse, initialisez le pushnotificationservice void main() async { widgetsflutterbinding ensureinitialized(); await firebase initializeapp(); // initialize parse as before // initialize push notifications pushnotificationservice pushnotificationservice = pushnotificationservice(); await pushnotificationservice init(); runapp(myapp()); } 9 6 envoi de notifications push depuis back4app vous pouvez envoyer des notifications push en utilisant cloud code ou directement depuis votre serveur 9 6 1 envoi de notification lors d'une demande d'ami lorsqu'un utilisateur envoie une demande d'ami, vous pouvez envoyer une notification push au destinataire dans friend service dart , modifiez la sendfriendrequest méthode future\<bool> sendfriendrequest(parseuser fromuser, parseuser touser) async { // existing code to create friend request // send push notification final pushquery = querybuilder\<parseinstallation>(parseinstallation forquery()) whereequalto('user', touser); await parsepush() send( pushpayload( query pushquery, notification parsenotification( title 'new friend request', alert '${fromuser username} sent you a friend request', ), ), ); return response success; } note assurez vous d'avoir associé l'installation avec l'utilisateur 9 7 associer l'installation avec l'utilisateur lorsqu'un utilisateur se connecte, associez son installation avec son compte utilisateur dans auth service dart , après une connexion réussie future\<bool> login(string username, string password) async { user = parseuser(username, password, null); final response = await user! login(); if (response success) { // associate installation with user final installation = await parseinstallation currentinstallation(); installation set('user', user); await installation save(); notifylisteners(); return true; } else { user = null; return false; } } remarque les notifications push nécessitent une configuration supplémentaire à la fois du côté client et serveur vous devez gérer différents scénarios, tels que les notifications en arrière plan et les autorisations des utilisateurs, qui dépassent le cadre de ce tutoriel conclusion félicitations ! vous avez construit les bases d'une application de réseau social en utilisant flutter et back4app cette application comprend l'authentification des utilisateurs, la gestion des profils et une fonctionnalité de fil d'actualités bien que la mise en œuvre de connexions d'amis complètes, de messagerie et de notifications dépasse le cadre de ce tutoriel, vous avez maintenant la structure nécessaire pour continuer à développer votre application prochaines étapes connexions d'amis implémentez des fonctionnalités de demande d'amis messagerie ajoutez des fonctionnalités de chat en temps réel en utilisant les requêtes en direct notifications intégrez des notifications push pour l'engagement des utilisateurs améliorations de l'ui améliorez l'interface utilisateur et l'expérience utilisateur sécurité assurez la sécurité des données et la confidentialité en définissant des acl appropriées dans back4app ressources supplémentaires documentation de back4app https //www back4app com/docs guide du sdk parse pour flutter https //docs parseplatform org/flutter/guide/ documentation officielle de flutter https //flutter dev/docs documentation du package provider https //pub dev/packages/provider bon codage !