Hope all are well i am working on a flutter app where i got stuck at chat module the chat is working fine and sending messages as well. But i want to show the persons whom i chat with most recent on chat screen page.
Like messenger whats app when we chat with someone it comes on chat screen like that.
Here is my chatroom screen
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:uuid/uuid.dart';
class chatroom extends StatelessWidget {
final Map<String, dynamic> userMap;
final String chatRoomId;
chatroom({required this.chatRoomId, required this.userMap});
final TextEditingController _message = TextEditingController();
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
File? imageFile;
Future getImage() async {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((xFile) {
if (xFile != null) {
imageFile = File(xFile.path);
uploadImage();
}
});
}
Future uploadImage() async {
String fileName = Uuid().v1();
int status = 1;
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName)
.set({
"sendBy": _auth.currentUser!.displayName,
"message":"",
"type":"img",
"time": FieldValue.serverTimestamp(),
});
var ref =
FirebaseStorage.instance.ref().child('images').child("$fileName.jpg");
var uploadTask = await ref.putFile(imageFile!).catchError((error) async{
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName).delete();
status = 0 ;
});
if(status==1){
String imageUrl = await uploadTask.ref.getDownloadURL();
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName).update({
"message": imageUrl,
});
print(imageUrl);
}
}
void onSendMessage() async {
if (_message.text.isNotEmpty) {
Map<String, dynamic> messages = {
"sendBy": _auth.currentUser!.displayName,
"message": _message.text,
"type": "text",
"time": FieldValue.serverTimestamp(),
};
await _firestore
.collection('chatroom')
.doc(chatRoomId)
.collection('chats')
.add(messages);
_message.clear();
} else {
print("Enter Some Text");
}
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.black,
title: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: StreamBuilder<DocumentSnapshot>(
stream: _firestore
.collection("registration")
.doc(userMap['uid'])
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Container(
child: Column(
children: [
Text(
userMap['name'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 18,
),
),
Padding(
padding: const EdgeInsets.only(right: 100),
child: Text(
snapshot.data!['status'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 14,
),
),
),
],
),
);
} else {
return Container();
}
},
),
),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: size.height / 1.25,
width: size.width,
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('chatroom')
.doc(chatRoomId)
.collection('chats')
.orderBy("time", descending: false)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (context, index) {
Map<String, dynamic> map = snapshot.data!.docs[index]
.data() as Map<String, dynamic>;
return messages(size, map,context);
},
);
} else {
return Container();
}
},
),
),
],
),
),
bottomNavigationBar: Container(
color: Colors.white,
height: size.height / 10,
width: size.width,
alignment: Alignment.center,
child: Container(
height: size.height / 12,
width: size.width / 1.1,
child: Row(
children: [
Container(
height: size.height / 17,
width: size.width / 1.3,
child: TextField(
controller: _message,
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: () => getImage(),
icon: Icon(Icons.photo),
),
hintText: "Send Message",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
),
IconButton(
onPressed: onSendMessage,
icon: Icon(Icons.send),
)
],
),
),
),
);
}
Widget messages(Size size, Map<String, dynamic> map, BuildContext context) {
return map['type'] == "text"
? Container(
width: size.width,
alignment: map['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 14),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.blue,
),
child: Text(
map['message'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
),
)
: Container(
height: size.height / 2.5,
width: size.width,
padding: EdgeInsets.symmetric(vertical: 5,horizontal: 5),
alignment: map['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: InkWell(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (_)=> ShowImage(imageURl: map['message'],
),
),
),
child: Container(
height: size.height / 2.5,
width: size.width / 2,
decoration: BoxDecoration(
border: Border.all(),
),
alignment: map['message']!="" ? null :Alignment.center,
child: map['message'] != ""
? Image.network(map['message'],fit: BoxFit.cover,)
: CircularProgressIndicator(),
),
),
);
}
}
class ShowImage extends StatelessWidget {
final imageURl;
const ShowImage({required this.imageURl, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
body: Container(
height: size.height,
width: size.width,
color: Colors.black,
child: Image.network(imageURl),
),
);
}
}
here is my chathome screen
import 'package:bpe_application/chat/chatroom.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
class Conversation extends StatefulWidget {
@override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State<Conversation> with WidgetsBindingObserver {
late final String chatRoomId;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addObserver(this);
setStatus("Online");
}
void setStatus(String status) async{
await _firestore.collection('registration').doc(_auth.currentUser!.uid).update({
"status": status,
});
}
@override
void didChangeAppLifecycleState(AppLifecycleState state){
if (state == AppLifecycleState.resumed){
//online
setStatus("Online");
}else{
//offline
setStatus("Offline");
}
}
final FirebaseAuth _auth = FirebaseAuth.instance;
Map<String, dynamic>? userMap;
bool isLoading= false;
final TextEditingController _search = TextEditingController();
ScrollController scrollController = ScrollController();
String chatroomId(String user1, String user2){
if(user1[0].toLowerCase().codeUnits[0] > user2.toLowerCase().codeUnits[0]){
return "$user1$user2";
}else{
return "$user2$user1";
}
}
void onSearch() async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
setState(() {
isLoading = true;
});
await _firestore.collection("registration").
where("email", isEqualTo: _search.text).
get().then((value) {
setState(() {
userMap= value.docs[0].data();
isLoading=false;
});
print(userMap);
}
);
}
void listView() async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
setState(() {
isLoading = true;
});
await _firestore.collection("registration").
where("email", isEqualTo: _search.text).
get().then((value) {
setState(() {
userMap= value.docs[0].data();
isLoading=false;
});
print(userMap);
}
);
}
@override
Widget build(BuildContext context) {
final size= MediaQuery.of(context).size;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //top bar color
systemNavigationBarColor: Colors.black, //bottom bar color
systemNavigationBarIconBrightness: Brightness.dark,
));
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
title: Padding(
padding: const EdgeInsets.fromLTRB(70, 0, 0, 0),
child: Text(
"Chat",
style: GoogleFonts.limelight(color: Colors.white),
),
),
),
body: isLoading? Center(
child: Container(
height: size.height/20,
width: size.width/20,
child: CircularProgressIndicator(),
),
)
: ClipRRect(
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(40.0),
topRight: const Radius.circular(40.0),
),
child: Container(
height: 800.0,
width: double.infinity,
color: Colors.grey.shade200,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
height: 10,
),
Container(
height: size.height/14,
width: size.width,
alignment: Alignment.center,
child: Container(
height: size.height/14,
width: size.width/1.2,
child: TextField(
controller: _search,
decoration: InputDecoration(
hintText: "Search",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
)
),
),
),
),
SizedBox(
height: size.height/70,
),
ElevatedButton(
onPressed: onSearch,
child: Text(
"Search",style: GoogleFonts.roboto(
color: Colors.white,
),
),
),
SizedBox(
height: size.height/60,
),
userMap != null
? ListTile(
onTap: () {
String roomId = chatroomId(
_auth.currentUser!.displayName!,
userMap!['name']);
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => chatroom(
chatRoomId: roomId,
userMap: userMap!,
),
),
);
},
leading: Icon(
Icons.account_box,
color: Colors.black,
),
title: Text(
userMap!['name'],
style: GoogleFonts.roboto(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w500,
),
),
subtitle: Text(userMap!['email']),
trailing: Icon(
Icons.chat,
color: Colors.black,
),
)
: Container(),
],
),
),
),
),
);
}
}
I am not using shared preference it's without shared preferences and only show persons when i searched for them. Want to show recent persons i chat with with searched feature as well.
Firebase Image enter image description here
Please note again i am not using shared preferences