I have an archaic solution for my problem, but it’s quickly become cumbersome and not as robust. I want to switch to a riverpod provider and am studying how to do so, but I want to put this question out there at the same time. For simplicity, my app is similar to BlaBlaCar. Lots of trips listed, and then users can request to be picked up. The general flow goes like this:
To call the same document ID from Firestore, my solution has been just to pass a detailDocument parameter over and over. In my trips page, I have a streambuilder that displays the document:
StreamBuilder<QuerySnapshot<Object?>> tripStreamBuilder() {
return StreamBuilder<QuerySnapshot>(
stream: tripStream.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
return ListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Card(
child: ListTile(
// leading: Text((data['departureDate']).toString()),
title: Text('From ${data['departure']}'),
subtitle: Text('To ${data['arrival']}'),
trailing: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text((data['departureDate']).toString()),
Text('Leaving at ${data['departureTime']}'),
],
),
),
onTap: () {
Navigator.of(context, rootNavigator: true)
.push(MaterialPageRoute(
builder: (context) => TripDetails(
detailDocument: document,
)));
},
),
);
}).toList(),
);
},
);
From here, I just keep making detailDocument a parameter. For exmaple in my trip details:
class TripDetails extends ConsumerStatefulWidget {
const TripDetails({super.key, required this.detailDocument});
final DocumentSnapshot detailDocument;
And jointrip class:
class JoinTrip extends ConsumerStatefulWidget {
const JoinTrip({
super.key,
required this.detailDocument,
});
final DocumentSnapshot detailDocument;
So my question is how can I pass the document ID into a riverpod provider? And one that gets disposed and reset as users click on different trips.
2
Answers
Ok so not sure if this is the best solution, but I ended up making a StateNotifierProvider out of the DocumentSnapshot class from Firestore.
Then once a user clicks on a trip, I pass the value to the provider via
Then I can just call it for whatever field in the doc I need.
It's working for now...
You shouldn’t pass the
id
of your document to pages. You can check this example from the official documentation.In you case, you can have a provider that saves the
id
. So whenever you need to fetch or do something about the same id, you watch its value and when you need to change it, you can change the id in that provider.Let’s say we have two providers as follow:
tripIdProvider
has the latest clickedid
, andtripProvider
will watch thisid
and updates and fetch the new values if theid
changes. It fetches the document of that id from the Firebase.Now if user clicks another object having another id, in the callback of pressing/tapping that object, you can do something like this:
This will change the
id
and becausetripProvider
iswatch
ing that providers’ value, it will be triggered again and will fetch new data for the newid
.It’s also good to check stateNotifier.