I'm using a StreamBuilder with this query:
FirebaseFirestore.instance.collection('driver').where('onlineStatus', isEqualTo: true).where('uid', isEqualTo: _driver.uid).snapshots()
So, I'm listening to a specefic driver if he online(onlineStatus = true) or offline(onlineStatus = false) where uid = _driver.uid (I'm storing the driver uid in Driver object).
This is the code:
getSelectedDriver(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _driversCollection
.where('onlineStatus', isEqualTo: true)
.where('uid', isEqualTo: _driver.uid)
.snapshots(),
builder: (streamContext, snapshot) {
if (snapshot.hasData) {
print('----- hasData -----');
return myWidget;
} else {
print('----- !!!!!hasData -----');
return changeTheWidget;
}
});
}
And in myWidget:
myWidget = StreamBuilder<QuerySnapshot>(
stream: _requestsCollection.where('uid', isEqualTo: requestId).snapshots(),
builder: (streamContext, snapshot) {
if (snapshot.hasData) {
final requests = snapshot.data.docs;
if (requests.isNotEmpty) {
var requestStatus = requests[0]['requestStatus'];
if (requestStatus == 'Accepted') {
print('----- Accepted -----');
return SelectedDriverCard(
...
onTap: () {
setState(() {
waitingForDriver = false;
});
},
);
}
else if (requestStatus == 'Refused') {
print('----- Refused -----');
return SelectedDriverCard(
fullName: _driver.fullName,
...
onTap: () async {
await _requestsCollection.doc(requestId).delete();
setState(() {
requested = false;
requestId = '';
});
},
);
}
else {
print('----- Waiting -----');
return SelectedDriverCard(
fullName: _driver.fullName,
...
onTap: () async {
await _requestsCollection.doc(requestId).delete();
setState(() {
requested = false;
requestId = '';
});
},
);
}
}
return SelectedDriverCard(
fullName: _driver.fullName,
...
onTap: () async {
await _requestsCollection.doc(requestId).delete();
setState(() {
requested = false;
});
},
);
} else {
print('----------------snapshot.!!!!hasData----------------');
return Loading();
}
},
)
And in changeTheWidget:
changeTheWidget = Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('It looks like the driver went offline...'),
Text('Wait until he back online'),
Loading(),
Text('Or find another one'),
GestureDetector(
child: Icon(Icons.arrow_back),
onTap: () async {
await _requestsCollection.doc(requestId).delete();
setState(() {
requested = false;
selectedDriver = false;
});
},
),
],
);
So, how my code works:
1- When I select a driver I call the method getSelectedDriver(context) (First code above).
2- I'm using this StreamBuilder just to keep checking of driver in case he went offline.
3- So, while he's online, I make a request to him, and that happens in another StreamBuilder in myWidget , I'm listening to the request I've made to driver, so he can Accept it or Refuse it.
4- If the driver goes offline, I return changeTheWidget.
Now, everything works fine but when I choose the driver then the request StreamBuilder pop up normal, but (with another device) I switch the Online Status of the driver to offline and wait for the Stream to show other Widget that tells me the driver went offline as you can see in changeTheWidget, It doesn't change, the Stream keeps listening to the data and read the data like the driver didn't change his status.
I mean the snapshot keeps getting in the if(snapshot.data.docs) condition but the Query logically it must returns no data so it shows the offline message to me.
P.S: Code has no Errors, it works properly.
I hope I made everything clear. If something is not clear, tell me I'll try to explain more.