I have a stream that apparently does not return a value. Instead of returning anything, the snapshot I use in my Streambuilder returns the yellow container (see code below) which is returned when my snapshot has no data. Any idea what causes this issue?
Below you will all functions, the stream as well as my Streambuilder.
Here is the updated stream. The otherUserId print statement is NOT printed. Maybe the error lies somewhere here.
Stream<List>? roomsListStream() async* {
try {
print("userId: $userId");
var rooms = FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots();
rooms.map((QuerySnapshot query) {
List<RoomsListModel> retVal = [];
for (var element in query.docs) {
// get other user id
String otherUserId = element["users"][0] == userId
? element["users"][1]
: element["users"][0];
print("otherUserId: $otherUserId");
// get other user details
getOtherUser(otherUserId).then((value) {
retVal.add(RoomsListModel(
roomId: element.id,
otherUserId: otherUserId,
avatar: value["photoUrl"],
name: value["name"],
lastMessage: element["latestMessage"],
lastMessageTime: element["latestMessageTime"]));
});
}
print(retVal);
return retVal;
});
} catch (e) {
print("Error: $e");
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:blabber_tech/services/auth.dart';
import 'package:blabber_tech/services/chat_services.dart';
import 'package:rxdart/rxdart.dart';
import 'package:blabber_tech/models/room_model.dart';
// Rooms List Model
class RoomsListModel {
String roomId;
String otherUserId;
String avatar;
String name;
String lastMessage;
Timestamp lastMessageTime;
RoomsListModel(
{required this.roomId,
required this.otherUserId,
required this.avatar,
required this.name,
required this.lastMessage,
required this.lastMessageTime});
}
class MyChatsScreen3 extends StatefulWidget {
static const String id = "mychats3_screen";
@override
State<MyChatsScreen3> createState() => _MyChatsScreenState();
}
// get other user details
Future getOtherUser(String id) async {
// get other user profile
var user = await FirebaseFirestore.instance
.collection("users")
.doc(id)
.get()
.then((value) => value.data()) as Map<String, dynamic>;
// return other user profile
return user;
}
class _MyChatsScreenState extends State<MyChatsScreen3> {
// get current user id
String userId = AuthService().getUserId();
// get all active chats
**Stream<List>? roomsListStream() {**
try {
FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots()
.map((QuerySnapshot query) {
List<RoomsListModel> retVal = [];
query.docs.forEach((element) {
retVal.add(RoomsListModel(
roomId: element.id,
otherUserId: element["users"][0] == userId
? element["users"][1]
: element["users"][0],
avatar: element["photoUrl"],
name: element["name"],
lastMessage: element["latestMessage"],
**lastMessageTime: element["latestMessageTime"]**));
});
return retVal;
});
} catch (e) {
print("Error: $e");
}
}
// List builder for mobile app
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
// create listview of all chats of current user and show last message and other user name and photo
child: **StreamBuilder(**
stream: roomsListStream(),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
**if (snapshot.hasData) {**
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
// show other user profile photo
//backgroundImage:
//NetworkImage(otherUser["profilePhotoUrl"]),
),
//title: Text(snapshot.data[index]["userName"]),
subtitle: Text(snapshot.data[index]["lastMessage"]),
);
},
);
} else {
return Container(
color: Colors.yellow,
);
}
},
),
),
);
}
}
CodePudding user response:
You forget to await
for FirebaseFirestore
result:
Stream<List>? roomsListStream() async* {
try {
var rooms = await FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots();
await rooms.map((QuerySnapshot query) async*{
List<RoomsListModel> retVal = [];
query.docs.forEach((element) {
retVal.add(RoomsListModel(
roomId: element.id,
otherUserId: element["users"][0] == userId
? element["users"][1]
: element["users"][0],
avatar: element["photoUrl"],
name: element["name"],
lastMessage: element["latestMessage"],
lastMessageTime: element["latestMessageTime"]));
});
yield retVal;
});
} catch (e) {
print("Error: $e");
}
}
and also change this:
if (snapshot.hasData) {
to this:
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {