- Here I am using provider in main.dart to stream "itemsInUserDocument" data from a document.
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<DocumentSnapshot>.value(
value: DatabaseService().itemsInUserDocument, <--- (1) Providing here
),
StreamProvider<User>.value(
value: AuthProvider().user,
),
],
- My problem is passing the userUID to the Stream query here. My document id's on Firestore is my userUID.
final userUID = "3SlUigYBgsNgzjU8a9GSimhAhuu1"; <-- (2) Need to pass to stream "userID' below??
class DatabaseService {
Stream<DocumentSnapshot> get itemsInUserDocument {
final DocumentReference userData = Firestore.instance.collection('userdata').document(userUID);
return userData.snapshots();
}
}
- Here I am using the list in down the widget tree.
@override
Widget build(BuildContext context) {
final userTaskDone = Provider.of<DocumentSnapshot>(context);
List taskList = []; <-- (3) Using the list here.
taskList = userTaskDone['tasks'].toList();
print(taskList);
It currently works and I am getting the streamed data in section (3) as is now, but I need to pass the Firebase user UID into the stream in section (2).
I can get the user UID in a stateful widget with setState function but everything I have tried doesn't work or seems like I am duplicating things too much, I am trying to use Provider to manage state properly.
I can get the userUID with provider as well, but you can only use it on a (context), where my notifier section (2) is only a class.
PLEASE help me with a solution.
EDIT:
I have tried the edits and the result is as follow:
Getting this critical error from provider when I enter the screen where it used to work before these changes to main.dart.
Here is the full code for main.dart with edits as it is now:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.dark(),
title: 'Sendr',
home: MainScreen(),
routes: {
SplashPage.id: (context) => SplashPage(),
LoginScreen.id: (context) => LoginScreen(),
NavigatorScreen.id: (context) => NavigatorScreen(),
CragSelectionScreen.id: (context) => CragSelectionScreen(),
CragRoutesScreen.id: (context) => CragRoutesScreen(),
RouteDetailScreen.id: (context) => RouteDetailScreen(),
MapScreen.id: (context) => MapScreen(),
},
);
}
}
///Authentication Logic
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthProvider().user,
child: Consumer<User>(
builder: (context, user, __) {
if (user == null) {
return LoginScreen();
} else {
return MultiProvider(
providers: [
Provider<DatabaseService>.value(
value: DatabaseService(user.uid),
),
],
child: NavigatorScreen(),
);
}
},
),
);
}
}
This is my Database Service:
import 'package:cloud_firestore/cloud_firestore.dart';
class DatabaseService {
DatabaseService(this.uid);
final String uid;
Stream<DocumentSnapshot> get itemsInUserDocument {
final DocumentReference userData =
Firestore.instance.collection('userdata').document(uid);
return userData.snapshots();
}
}
I have made no change to my step (3) where I am using it, is this where my problem might be now?
I am trying to do more research on this. Working through the provider docs. If I understand your suggestion correctly, we are streaming the User value from AuthProvider at the top, then consume the User value just below it then passing the user.uid value to the DatabaseService, which is used down the widget tree again. Looks like I am almost there from your help. If you don't mind, please let me know what you think of the provider error on the screen. Much appreciated.