Flutter Templates
Erstellen einer sozialen Netzwerk-App mit Flutter und Back4App
54 min
einführung die erstellung einer social networking app kann eine komplexe aufgabe sein, aber mit flutter und back4app können sie den entwicklungsprozess optimieren dieses tutorial führt sie durch den aufbau einer voll funktionsfähigen social networking app, die benutzerauthentifizierung, profilverwaltung, nachrichtenfeeds, freundeverbindungen, messaging und benachrichtigungen umfasst am ende dieses tutorials haben sie eine funktionale social networking app mit den folgenden funktionen benutzerauthentifizierung sichere anmelde und registrierungsprozesse benutzerprofile bearbeitbare profile mit benutzerinformationen nachrichtenfeeds anzeige von beiträgen von freunden und dem benutzer freundeverbindungen möglichkeit, freundschaftsanfragen zu senden und zu akzeptieren messaging echtzeit chat zwischen benutzern benachrichtigungen push benachrichtigungen für freundschaftsanfragen, nachrichten und beitragsinteraktionen voraussetzungen um diesem tutorial zu folgen, benötigen sie flutter sdk auf ihrem computer installiert folgen sie der offiziellen flutter installationsanleitung https //flutter dev/docs/get started/install für ihr betriebssystem grundkenntnisse in flutter und dart wenn sie neu bei flutter sind, lesen sie die flutter dokumentation https //flutter dev/docs durch, um sich mit den grundlagen vertraut zu machen eine ide oder einen texteditor wie visual studio code oder android studio ein back4app konto melden sie sich für ein kostenloses konto bei back4app https //www back4app com/ an parse server sdk für flutter in ihr projekt integriert erfahren sie, wie sie es einrichten, indem sie die back4app flutter sdk anleitung https //www back4app com/docs/flutter/parse flutter sdk befolgen schritt 1 – einrichten des flutter projekts 1 1 erstellen sie ein neues flutter projekt öffnen sie ihr terminal und führen sie aus flutter create social app navigiere zum projektverzeichnis cd social app 1 2 abhängigkeiten hinzufügen öffne pubspec yaml und füge die folgenden abhängigkeiten hinzu 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 führe flutter pub get aus, um die pakete zu installieren hinweis wir verwenden parse server sdk flutter für die back4app integration provider für das state management image picker zum auswählen von profil und beitragsbildern cached network image für effizientes laden von bildern firebase messaging für push benachrichtigungen uuid zur generierung eindeutiger ids schritt 2 – back4app einrichten 2 1 erstellen sie eine neue back4app anwendung melden sie sich bei ihrem back4app dashboard https //dashboard back4app com/ an klicken sie auf "neue app erstellen" geben sie einen namen für ihre anwendung ein, z b "socialapp" , und klicken sie auf "erstellen" 2 2 richten sie die datenmodelle ein wir müssen mehrere klassen in back4app erstellen benutzer eingebaute klasse für die benutzerauthentifizierung profil speichert benutzerprofilinformationen beitrag speichert benutzerbeiträge freundschaftsanfrage verwaltet freundschaftsanfragen zwischen benutzern nachricht speichert nachrichten zwischen benutzern 2 2 1 profilklasse navigieren sie zu der "datenbank" sektion klicken sie auf "klasse erstellen" im modal wählen sie "benutzerdefiniert" geben sie "profil" als klassennamen ein klicken sie auf "klasse erstellen" fügen sie die folgenden spalten hinzu benutzer typ pointer< user> benutzername typ string vollständiger name typ string biografie typ string profilbild typ datei 2 2 2 beitragsklasse erstellen sie eine "post" klasse mit den folgenden spalten benutzer typ pointer< user> inhalt typ string bild typ file erstelltam typ date 2 2 3 friendrequest klasse erstellen sie eine "friendrequest" klasse mit den folgenden spalten vonbenutzer typ pointer< user> zubenutzer typ pointer< user> status typ string (werte "ausstehend", "akzeptiert", "abgelehnt") 2 2 4 message klasse erstellen sie eine "message" klasse mit den folgenden spalten vonbenutzer typ pointer< user> zubenutzer typ pointer< user> inhalt typ string erstelltam typ date 2 3 anwendungsanmeldeinformationen erhalten navigieren sie zu app einstellungen > sicherheit & schlüssel notieren sie ihre anwendungs id und client schlüssel schritt 3 – initialisierung von parse in ihrer flutter app öffnen sie lib/main dart und ändern sie es wie folgt 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(), ), ); } } ersetzen sie 'your application id' und 'your client key' durch ihre back4app anmeldeinformationen wir verwenden changenotifierprovider zur verwaltung des authentifizierungsstatus schritt 4 – implementierung der benutzeranmeldung 4 1 erstellen sie den authentifizierungsdienst erstellen sie ein neues verzeichnis mit dem namen services unter lib und fügen sie eine datei mit dem namen 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 erstellen sie die anmelde und registrierungsbildschirme erstellen sie ein verzeichnis mit dem namen screens unter lib und fügen sie login screen dart und signup screen dart , hinzu 4 2 1 anmeldescreen // 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 registrierungsbildschirm // 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')), ], ), ), ); } } schritt 5 – benutzerprofile einrichten 5 1 profilservice erstellen fügen sie eine datei mit dem namen profile service dart unter 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 profilmodell erstellen fügen sie eine datei mit dem namen profile dart unter 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 profilbildschirm erstellen fügen sie eine datei mit dem namen profile screen dart unter 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')), ], ), ), ); } } schritt 6 – implementierung von nachrichten feeds 6 1 erstelle post service fügen sie eine datei mit dem namen post service dart unter 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 erstelle post modell fügen sie eine datei mit dem namen post dart unter 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 erstellen sie den startbildschirm ändern sie home screen dart unter 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), ), ); }, ), ), ], ), ); } } schritt 7 – freundesverbindungen hinzufügen in diesem schritt werden wir freundschaftsverbindungen zwischen benutzern implementieren benutzer können freundschaftsanfragen senden, diese annehmen oder ablehnen und ihre freundesliste einsehen wir werden die datenmodelle ändern, dienste erstellen und die benutzeroberfläche aktualisieren, um diese funktionalität zu unterstützen 7 1 aktualisierung des datenmodells wir haben bereits die friendrequest klasse in back4app mit den folgenden spalten erstellt fromuser zeiger auf user touser zeiger auf user status zeichenfolge (werte "pending", "accepted", "rejected") zusätzlich müssen wir die freundesliste eines benutzers verfolgen wir können dies tun, indem wir eine friends beziehung in der user klasse hinzufügen 7 1 1 freundesbeziehung zur benutzerklasse hinzufügen gehe in back4app zur user klasse klicke auf die "+" schaltfläche, um eine neue spalte hinzuzufügen benenne die spalte "friends" und setze den typ auf relation < user> 7 2 erstelle einen freundschaftsanfrage service erstelle eine datei mit dem namen friend service dart unter 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 aktualisieren sie die benutzeroberfläche 7 3 1 benutzer suchen bildschirm hinzufügen erstellen sie eine datei mit dem namen search users screen dart unter 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 freundschaftsanfragen bildschirm erstellen sie eine datei mit dem namen friend requests screen dart unter 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 aktualisieren sie die navigation des startbildschirms in home screen dart , fügen sie die navigation zu den bildschirmen für die benutzersuche und die freundschaftsanfragen hinzu // 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 aktualisieren sie den news feed, um die beiträge von freunden anzuzeigen ändern sie die getposts methode in post service dart um beiträge vom benutzer und seinen freunden abzurufen // 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 \[]; } } schritt 8 – implementierung der nachrichtenübermittlung in diesem schritt fügen wir eine echtzeitkommunikation zwischen benutzern mit live abfragen hinzu 8 1 live abfragen in back4app aktivieren gehe in deinem back4app app dashboard zu app einstellungen > servereinstellungen unter server url , notiere dir deine server url (z b https //your app name back4app io ) live abfragen sind standardmäßig in back4app aktiviert 8 2 live abfragen in flutter einrichten das parse server sdk flutter paket enthält unterstützung für live abfragen 8 3 messaging dienst erstellen erstelle eine datei mit dem namen message service dart unter 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 nachrichtenmodell erstellen füge eine datei mit dem namen message dart unter 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 erstelle den chat bildschirm fügen sie eine datei mit dem namen chat screen dart unter 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 benutzeroberfläche aktualisieren, um den chat zu starten sie können den chat von der freundesliste oder dem bildschirm zur benutzersuche aus starten in der freundesliste, wenn freunde angezeigt werden, fügen sie eine schaltfläche hinzu, um einen chat zu starten // inside the listtile for a friend trailing iconbutton( icon icon(icons chat), onpressed () { navigator push( context, materialpageroute(builder ( ) => chatscreen(otheruser friend)), ); }, ), schritt 9 – push benachrichtigungen hinzufügen die implementierung von push benachrichtigungen umfasst die einrichtung von firebase cloud messaging (fcm) und die integration mit back4app 9 1 firebase cloud messaging konfigurieren 9 1 1 firebase projekt einrichten gehe zu firebase console https //console firebase google com/ und erstelle ein neues projekt füge eine android und/oder ios app zu deinem projekt hinzu für android benötigst du den paketnamen (applicationid) für ios benötigst du die bundle id 9 1 2 konfigurationsdateien herunterladen für android lade google services json herunter und platziere es in android/app/ für ios lade googleservice info plist herunter und füge es deinem xcode projekt unter runner hinzu 9 2 firebase messaging paket hinzufügen stelle sicher, dass du firebase messaging zu deiner pubspec yaml dependencies firebase messaging ^11 2 8 führe flutter pub get aus, um zu installieren 9 3 firebase in flutter initialisieren ändern sie 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 firebase messaging konfigurieren erstellen sie eine datei mit dem namen push notification service dart unter 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 aktualisieren sie main dart um push benachrichtigungen zu initialisieren in main dart , nach der initialisierung von parse, initialisieren sie den 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 push benachrichtigungen von back4app senden sie können push benachrichtigungen mit cloud code oder direkt von ihrem server aus senden 9 6 1 benachrichtigung bei freundschaftsanfrage senden wenn ein benutzer eine freundschaftsanfrage sendet, können sie eine push benachrichtigung an den empfänger senden in friend service dart , ändern sie die sendfriendrequest methode 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; } hinweis stellen sie sicher, dass sie die installation mit dem benutzer verknüpft haben 9 7 installation mit benutzer verknüpfen wenn sich ein benutzer anmeldet, verknüpfen sie seine installation mit seinem benutzerkonto in auth service dart , nach erfolgreicher anmeldung 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; } } hinweis push benachrichtigungen erfordern zusätzliche einstellungen sowohl auf der client als auch auf der serverseite sie müssen verschiedene szenarien behandeln, wie z b hintergrundbenachrichtigungen und benutzerberechtigungen, die über den rahmen dieses tutorials hinausgehen fazit herzlichen glückwunsch! sie haben das fundament einer social networking app mit flutter und back4app erstellt diese app umfasst die benutzerauthentifizierung, das profilmanagement und eine nachrichtenfeed funktion während die implementierung vollständiger freundeverbindungen, messaging und benachrichtigungen über den rahmen dieses tutorials hinausgeht, haben sie nun die notwendige struktur, um ihre app weiter auszubauen nächste schritte freundeverbindungen implementieren sie funktionen für freundschaftsanfragen messaging fügen sie echtzeit chat funktionen mit live queries hinzu benachrichtigungen integrieren sie push benachrichtigungen für die benutzerbindung ui verbesserungen verbessern sie die benutzeroberfläche und das benutzererlebnis sicherheit stellen sie die datensicherheit und den datenschutz sicher, indem sie geeignete acls in back4app festlegen zusätzliche ressourcen back4app dokumentation https //www back4app com/docs parse sdk für flutter leitfaden https //docs parseplatform org/flutter/guide/ offizielle flutter dokumentation https //flutter dev/docs dokumentation des provider pakets https //pub dev/packages/provider viel spaß beim programmieren!