Flutter Templates
Einen Echtzeit-Chat-Anwendung in Flutter mit Back4App erstellen
35 min
einführung die erstellung einer chat anwendung umfasst das management von echtzeitdaten, benutzerauthentifizierung, medienverwaltung und effiziente datenspeicherung in diesem tutorial lernen sie, wie sie eine echtzeit chat anwendung in flutter erstellen, die einzel und gruppengespräche, nachrichtenstatus und medienfreigabe unterstützt wir verwenden back4app – einen backend as a service, der von parse server betrieben wird – um die backend funktionalitäten zu verwalten am ende dieses tutorials haben sie eine voll funktionsfähige chat app mit den folgenden funktionen benutzerauthentifizierung sichere anmelde und registrierungsprozesse echtzeit nachrichten sofortige nachrichtenübermittlung mit live queries benutzerpräsenz verfolgung des online/offline status von benutzern medienlagerung senden und empfangen von bildern in chats nachrichtenverlauf persistierung von chatverläufen für benutzer 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 grundkenntnisse in flutter und dart 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 zu ihrem projekt hinzugefügt übersicht wir werden eine chat anwendung mit den folgenden komponenten erstellen benutzerauthentifizierung benutzer können sich registrieren und anmelden kontaktliste eine liste von benutzern anzeigen, mit denen man chatten kann chat bildschirm echtzeit nachrichtenoberfläche medienfreigabe möglichkeit, bilder zu senden und zu empfangen online status online /offline status der benutzer anzeigen 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 chat app navigieren sie zum projektverzeichnis cd chat app 1 2 abhängigkeiten hinzufügen öffnen sie pubspec yaml und fügen sie die folgenden abhängigkeiten hinzu dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 image picker ^0 8 4+3 cached network image ^3 2 0 uuid ^3 0 4 führen sie flutter pub get aus, um die pakete zu installieren parse server sdk flutter interagieren sie mit back4app image picker bilder aus der galerie oder kamera auswählen cached network image effizientes laden und caching von bildern uuid einzigartige identifikatoren generieren 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 "chatapp" , und klicken sie auf "erstellen" 2 2 klassen und datenmodell konfigurieren wir werden die folgenden klassen erstellen benutzer (standard parse klasse) speichert benutzerinformationen nachricht speichert chatnachrichten chatraum stellt einen chat zwischen benutzern dar 2 2 1 benutzerklasse felder benutzername string passwort string e mail string istonline boolean avatar datei (optional) die benutzer klasse ist eingebaut; wir müssen nur sicherstellen, dass sie die zusätzlichen felder hat 2 2 2 nachrichtenklasse felder absender pointer< user> empfänger pointer< user> chatroomid string inhalt string bild datei (optional) erstelltam datum/uhrzeit (automatisch hinzugefügt) 2 2 3 chatroom klasse felder chatroomid string benutzer array of pointer< user> letztenachricht string aktualisiertam datetime (automatisch aktualisiert) 2 3 anwendungsanmeldeinformationen erhalten navigieren sie zu app einstellungen > sicherheit & schlüssel notieren sie sich 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 'screens/login screen dart'; // you'll create this file next 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 materialapp( title 'chat app', theme themedata( primaryswatch colors blue, ), home loginscreen(), ); } } ersetzen sie 'your application id' und 'your client key' durch ihre tatsächlichen back4app anmeldeinformationen schritt 4 – implementierung der benutzerauthentifizierung 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\ parse server sdk flutter/parse server sdk dart'; class authservice { future\<parseuser?> signup(string username, string email, string password) async { var user = parseuser(username, password, email); var response = await user signup(); if (response success) { return user; } else { return null; } } future\<parseuser?> login(string username, string password) async { var user = parseuser(username, password, null); var response = await user login(); if (response success) { return user; } else { return null; } } future\<void> logout() async { var user = await parseuser currentuser() as parseuser?; await user? logout(); } future\<parseuser?> getcurrentuser() async { return await parseuser currentuser() as parseuser?; } } 4 2 erstellen sie anmelde und registrierungsbildschirme erstellen sie ein neues verzeichnis namens screens unter lib und fügen sie dateien mit den namen login screen dart und signup screen dart 4 2 1 anmeldeseite // lib/screens/login screen dart import 'package\ flutter/material dart'; import ' /services/auth service dart'; import 'home screen dart'; import 'signup screen dart'; class loginscreen extends statelesswidget { final authservice authservice = authservice(); final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void login(buildcontext context) async { var user = await authservice login( usernamecontroller text trim(), passwordcontroller text trim(), ); if (user != null) { 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('chat 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(context), child text('login'), ), textbutton( onpressed () => navigator push( context, materialpageroute(builder (context) => 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 ' /services/auth service dart'; import 'home screen dart'; class signupscreen extends statelesswidget { final authservice authservice = authservice(); final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller emailcontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void signup(buildcontext context) async { var user = await authservice signup( usernamecontroller text trim(), emailcontroller text trim(), passwordcontroller text trim(), ); if (user != null) { navigator pushreplacement( context, materialpageroute(builder (context) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('sign up failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('chat app sign up'), ), 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(context), child text('sign up'), ), ], ), ), ); } } schritt 5 – implementierung der benutzerpräsenz 5 1 benutzer online status aktualisieren erstellen sie eine methode in authservice um den online status des benutzers zu aktualisieren // lib/services/auth service dart class authservice { // existing methods future\<void> updateuseronlinestatus(bool isonline) async { var user = await parseuser currentuser() as parseuser?; if (user != null) { user set('isonline', isonline); await user save(); } } } 5 2 online status bei anmeldung und abmeldung festlegen aktualisieren sie die anmelde und abmelde methoden // lib/services/auth service dart class authservice { // existing methods future\<parseuser?> login(string username, string password) async { var user = parseuser(username, password, null); var response = await user login(); if (response success) { await updateuseronlinestatus(true); return user; } else { return null; } } future\<void> logout() async { await updateuseronlinestatus(false); var user = await parseuser currentuser() as parseuser?; await user? logout(); } } schritt 6 – anzeige der kontaktliste 6 1 benutzer service erstellen erstellen sie user service dart unter services // lib/services/user service dart import 'package\ parse server sdk flutter/parse server sdk dart'; class userservice { future\<list\<parseuser>> getallusers() async { final querybuilder\<parseuser> queryusers = querybuilder\<parseuser>(parseuser forquery()); final parseresponse apiresponse = await queryusers query(); if (apiresponse success && apiresponse results != null) { return apiresponse results as list\<parseuser>; } else { return \[]; } } } 6 2 startbildschirm erstellen // lib/screens/home screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /services/user service dart'; import ' /services/auth service dart'; import 'chat screen dart'; class homescreen extends statefulwidget { @override homescreenstate createstate() => homescreenstate(); } class homescreenstate extends state\<homescreen> { final userservice userservice = userservice(); final authservice authservice = authservice(); list\<parseuser> users = \[]; parseuser? currentuser; @override void initstate() { super initstate(); fetchusers(); getcurrentuser(); } void getcurrentuser() async { currentuser = await authservice getcurrentuser(); } void fetchusers() async { var allusers = await userservice getallusers(); setstate(() { users = allusers where((user) => user username != currentuser? username) tolist(); }); } void logout(buildcontext context) async { await authservice logout(); navigator pushreplacementnamed(context, '/'); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('contacts'), actions \[ iconbutton(onpressed () => logout(context), icon icon(icons logout)), ], ), body listview\ builder( itemcount users length, itembuilder (context, index) { var user = users\[index]; return listtile( title text(user username ?? ''), subtitle text(user get('isonline') == true ? 'online' 'offline'), ontap () { navigator push( context, materialpageroute(builder (context) => chatscreen(receiver user)), ); }, ); }, ), ); } } schritt 7 – implementierung von echtzeit nachrichten mit live abfragen 7 1 live query client einrichten fügen sie die folgende abhängigkeit in pubspec yaml dependencies flutter sdk flutter parse server sdk flutter git url https //github com/parse community/parse sdk flutter git ref master dies stellt sicher, dass sie die neueste version mit live query unterstützung haben 7 2 live query in main dart // lib/main dart void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; const livequeryurl = 'wss\ //your app back4app io'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, livequeryurl livequeryurl, ); runapp(myapp()); } this is an additional text to be translated ersetzen sie 'your app' durch ihre back4app anwendungsunterdomäne 7 3 erstellen sie den chat bildschirm // lib/screens/chat screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ uuid/uuid dart'; import 'package\ image picker/image picker dart'; import ' /services/auth service dart'; import 'package\ cached network image/cached network image dart'; class chatscreen extends statefulwidget { final parseuser receiver; chatscreen({required this receiver}); @override chatscreenstate createstate() => chatscreenstate(); } class chatscreenstate extends state\<chatscreen> { final authservice authservice = authservice(); parseuser? currentuser; list\<parseobject> messages = \[]; string chatroomid = ''; final texteditingcontroller messagecontroller = texteditingcontroller(); late parselivelist\<parseobject> livemessages; @override void initstate() { super initstate(); getcurrentuser(); setupchatroom(); } void getcurrentuser() async { currentuser = await authservice getcurrentuser(); if (currentuser != null) { setuplivequery(); } } void setupchatroom() { string userid = currentuser! objectid!; string receiverid = widget receiver objectid!; chatroomid = userid compareto(receiverid) > 0 ? '$userid $receiverid' '$receiverid $userid'; } void setuplivequery() { querybuilder\<parseobject> querymessages = querybuilder\<parseobject>(parseobject('message')) whereequalto('chatroomid', chatroomid) orderbyascending('createdat'); livemessages = parselivelist\<parseobject>( querymessages, listeningincludes \['sender'], lazyloading false, ); setstate(() {}); } void sendmessage({string? content, parsefilebase? imagefile}) async { var message = parseobject('message') set('sender', currentuser) set('receiver', widget receiver) set('chatroomid', chatroomid) set('content', content ?? '') set('image', imagefile); await message save(); messagecontroller clear(); } void pickimage() async { final picker = imagepicker(); final pickedfile = await picker pickimage(source imagesource gallery, imagequality 50); if (pickedfile != null) { var file = parsefile(file(pickedfile path)); await file save(); sendmessage(imagefile file); } } @override void dispose() { livemessages dispose(); super dispose(); } @override widget build(buildcontext context) { if (currentuser == null || livemessages == null) { return scaffold( appbar appbar( title text('chat with ${widget receiver username}'), ), body center(child circularprogressindicator()), ); } return scaffold( appbar appbar( title text('chat with ${widget receiver username}'), ), body column( children \[ expanded( child parselivelistwidget\<parseobject>( query livemessages, reverse false, lazyloading false, childbuilder (context, snapshot) { if (snapshot failed) { return text('error ${snapshot error}'); } else if (snapshot hasdata) { var message = snapshot loadeddata!; var sender = message get\<parseuser>('sender')!; var isme = sender objectid == currentuser! objectid; var content = message get\<string>('content') ?? ''; var image = message get\<parsefilebase>('image'); return align( alignment isme ? alignment centerright alignment centerleft, child container( padding edgeinsets all(8), margin edgeinsets all(8), decoration boxdecoration( color isme ? colors blue\[100] colors grey\[300], borderradius borderradius circular(8), ), child column( crossaxisalignment crossaxisalignment start, children \[ if (content isnotempty) text(content), if (image != null) cachednetworkimage( imageurl image url!, placeholder (context, url) => circularprogressindicator(), errorwidget (context, url, error) => icon(icons error), ), ], ), ), ); } else { return container(); } }, ), ), divider(height 1), container( padding edgeinsets symmetric(horizontal 8), color colors white, child row( children \[ iconbutton( icon icon(icons photo), onpressed pickimage, ), expanded( child textfield( controller messagecontroller, decoration inputdecoration collapsed(hinttext 'type a message'), ), ), iconbutton( icon icon(icons send), onpressed () { if ( messagecontroller text trim() isnotempty) { sendmessage(content messagecontroller text trim()); } }, ), ], ), ), ], ), ); } } erklärung parselivelistwidget ein widget, das auf live abfrage updates hört und sich neu aufbaut, wenn sich die daten ändern sendmessage() sendet eine textnachricht oder ein bild pickimage() verwendet image picker , um ein bild auszuwählen und es als nachricht zu senden setuplivequery() richtet eine live abfrage ein, um auf neue nachrichten im chatraum zu hören schritt 8 – testen der app 8 1 führen sie die app aus führen sie in ihrem terminal aus flutter run 8 2 testnachrichten öffnen sie die app auf zwei geräten oder emulatoren melden sie sich mit verschiedenen benutzerkonten an oder registrieren sie sich wählen sie von einem konto den anderen benutzer aus der kontaktliste aus senden sie nachrichten und bilder; sie sollten in echtzeit auf beiden geräten erscheinen fazit herzlichen glückwunsch! sie haben eine echtzeit chat anwendung in flutter mit back4app erstellt diese app unterstützt benutzerauthentifizierung sicheres anmelden und registrieren echtzeit nachrichten sofortige updates mit live abfragen benutzerpräsenz online/offline statusverfolgung medienfreigabe senden und empfangen von bildern nachrichtenspeicher persistente chatnachrichten nächste schritte gruppenchats erweitern sie die app, um gruppengespräche zu unterstützen nachrichtenstatus implementieren sie lesebestätigungen und tippanzeigen push benachrichtigungen senden sie benachrichtigungen für neue nachrichten, wenn die app im hintergrund ist profilbilder ermöglichen sie benutzern, avatare hochzuladen sicherheitsverbesserungen sichern sie daten mit acls und rollenbasierten berechtigungen 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 parse live query https //docs parseplatform org/js/guide/#live queries viel spaß beim programmieren!