I try to implement fetch the data from firebase real time database by firebase Animated List. it's fetch the data correctly by insetting only query No need to other function and sorting but when add chat Message in to the list or fetch the data not scrolling to end to the bottom like other chat app like what's app and telegram. and i use flutter dart android studio firebase_auth: ^4.16.0 firebase_database: ^10.4.0 firebase_core: ^2.24.2 firebase_storage: ^11.6.0 cloud_firestore: ^4.14.0 I use letest of this version. the AnimatedList it receive controller but i try so many thing Not work please answer me it is important i work lange sacale project in my carryer Here is the ui of my animatedList view on android
- I Try create scroll controller
- set value in initState
- create function for animated list
- call it in send funciton
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:pasca/assets/custom_colors/colors.dart';
import 'package:pasca/methods/my_methods/shared_pref_method.dart';
import 'package:pasca/wediget/chat_messages_list.dart';
import 'package:pasca/wediget/snack_bar.dart';
import '../../second_code_test.dart';
class ChatRoom extends StatefulWidget {
String friendId;
String profileImage;
String friendName;
ChatRoom({
required this.friendId,
required this.profileImage,
required this.friendName,
});
@override
State<ChatRoom> createState() => _ChatRoomState();
}
class _ChatRoomState extends State<ChatRoom> {
final TextEditingController _messageController = TextEditingController();
final Query _dbRef = FirebaseDatabase.instance.ref().child('Chats');
String uid = '';
late ScrollController _scrollController;
List<Map<String, dynamic>> chatMessageList = [];
@override
void initState() {
super.initState();
fetchData();
// Listen for new messages and scroll to the bottom
_dbRef.onChildAdded.listen((event) {
_scrollController = ScrollController();
});
readMessage();
}
void fetchData() async {
String _uid = await SharedPref().getUid() ?? '';
// getting my id
setState(() {
uid = _uid;
});
}
@override
void dispose() {
super.dispose();
_scrollController.dispose();
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: CustomColors.primaryColor,
appBar: AppBar(
backgroundColor: CustomColors.secondaryColor,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back,
color: CustomColors.thirdColor,
),
),
title: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
widget.profileImage), // get profile from chat list
),
const SizedBox(
width: 10,
),
Text(
widget.friendName, // get name from chat list
style: const TextStyle(
color: CustomColors.thirdColor,
),
),
],
),
),
body: Column(
children: [
Expanded(
child: FirebaseAnimatedList(
query: _dbRef,
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
Map users = snapshot.value as Map;
// check message sender to my id b/c to put on the right side ot message
final bool isMe = users['sender'] == uid;
// check if message send by me or receive by me b/c in chat room display on my massage and friend message
if (users['sender'] == uid &&
users['receiver'] == widget.friendId ||
users['sender'] == widget.friendId &&
users['receiver'] == uid) {
return Align(
alignment:
isMe ? Alignment.centerRight : Alignment.centerLeft,
child: ChatMessageList(
// this is list item inside containt if it is me change border, alignment , and color based on bool answer
message: users['message'],
timeStamp: users['timeStamp'],
RBL: isMe ? 20 : 3,
RBR: isMe ? 3 : 20,
backColor: isMe
? CustomColors.secondaryColor
: CustomColors.fourthColor,
textColor: isMe
? CustomColors.fourthColor
: CustomColors.primaryColor,
inSideContaintAlign:
isMe ? const Alignment(1, 0) : const Alignment(-1, 0),
),
);
}
// if no message send me and myfriend it will return null container
return Container();
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(
right: 10,
bottom: 20,
),
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
width: size.width / 1.4,
decoration: BoxDecoration(
color: CustomColors.secondaryColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 20,
offset: const Offset(0, 5),
),
],
),
child: TextField(
controller: _messageController,
style: const TextStyle(
color: CustomColors.fourthColor,
),
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: IconButton(
onPressed: () {},
icon: const Icon(
Icons.photo_camera_outlined,
color: CustomColors.thirdColor,
),
),
suffixIcon: IconButton(
onPressed: () {},
icon: const Icon(
Icons.keyboard_voice_outlined,
color: CustomColors.thirdColor,
),
),
),
),
),
Container(
margin: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 20,
offset: const Offset(0, 5),
),
],
),
child: InkWell(
onTap: sendMessage,
child: const CircleAvatar(
backgroundColor: CustomColors.thirdColor,
radius: 25,
child: Icon(
Icons.send_outlined,
color: CustomColors.secondaryColor,
),
),
),
),
],
),
),
],
),
);
}
void readMessage() {
final DatabaseReference dbRef = FirebaseDatabase.instance.ref();
dbRef.child('Chats').orderByChild('timeStamp').onValue.listen((event) {
Map<dynamic, dynamic> chatMessage =
event.snapshot.value as Map<dynamic, dynamic>;
chatMessageList.clear();
List<MapEntry<dynamic, dynamic>> entries = chatMessage.entries.toList();
entries.sort((a, b) {
// Compare the "timeStamp" values for sorting
int timeStampA = a.value['timeStamp'];
int timeStampB = b.value['timeStamp'];
return timeStampA.compareTo(timeStampB);
});
for (int i = 0; i < entries.length; i++) {
MapEntry<dynamic, dynamic> entry = entries[i];
Map<String, dynamic> value = Map<String, dynamic>.from(entry.value);
// get user that sender is me or the message receive to me
if (value['sender'] == uid && value['receiver'] == widget.friendId ||
value['sender'] == widget.friendId && value['receiver'] == uid) {
chatMessageList.add(value);
}
}
}).onError((error) {
showSnackBar(context, error.toString());
});
}
void sendMessage() async {
// geting all nessasry info for send message e.g uid, friendId, message,date,database e.t.c .....
User? user = FirebaseAuth.instance.currentUser;
String uid = user!.uid;
String friendId = widget.friendId;
String message = _messageController.text;
String myId = await SharedPref().getUid() ?? uid;
DatabaseReference dbRef = FirebaseDatabase.instance.ref();
if (message.isNotEmpty && message != ' ' && message != ' ') {
// chat info map or object
Map<String, dynamic> chatData = {
'message': message,
'sender': myId,
'receiver': friendId,
'timeStamp': ServerValue.timestamp,
};
// inserting chat data
dbRef.child('Chats').push().set(chatData).then((_) {
// handle code when data inserted
_messageController.text = '';
}).catchError((error) {
showSnackBar(context, 'Error inserting data: $error');
});
}
_scrollController;
}
void scrollToBottom() {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
}
this is flutter dart code of animated list but i try to send message but not scroll automatically