Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

Flutter & Firebase - Use a Provider only locally for a single page

So, I am building an app with 3 screens so far: Login, Register and Home. Login and Register pages work just fine. I managed to use a Provider to listen to the user authentication state, and direct him either to the Login or Home page, depending on whether he is logged in or not.

Now for the Home Page: I basically want it to show a list of stores I have in my Firestore Database. To do this, I am wrapping the Scaffold with a StreamProvider<List>.value

But I I keep getting the following error message:

Error: Could not find the correct Provider<List> above this Home Widget

Now, if I understand this correctly, this is because the Provider for the stores is not declared in the main file, like I did with the Provider for the user authentication.

Is there any way of having the Provider for the stores declared just in this Home page, and not in the main file, since I do not need to access the database in the other pages?

  • main function:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MaterialApp(home: CondoApp()));
}

class CondoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthService().user,
      child: MaterialApp(
        theme: MyThemes(context).mainTheme,
        home: Wrapper(),
        routes: myRoutes,
      ),
    );
  }
}
  • wrapper (decides whether user is logged in or not, and then show the correct page)
class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);

    // return either StarPage or Home
    if (user == null) {
      return StartPage();
    } else {
      return Home();
    }
  }
}
  • home page
class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {

    final stores = Provider.of<List<Store>>(context);

    return StreamProvider<List<Store>>.value(
      value: DatabaseService().stores,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Title'),
        ),

        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(stores[0].name),
              Text(stores[0].image),
            ],
          ),
        ),
      ),
    );
  }
}
  • database file
class DatabaseService {

  final String uid;
  DatabaseService({ this.uid });

  // Collection reference
  final CollectionReference storeCollection = FirebaseFirestore.instance.collection('stores');

  // Make a store list from snapshot object
  List<Store> _storeListfromSnapshot(QuerySnapshot snapshot) {
    return snapshot.docs.map((doc){
      return Store(
        name:  doc.data()['name']  ?? '',
        image: doc.data()['image'] ?? ''
      );
    }).toList();
  }

  // Get stores stream
  Stream<List<Store>> get stores {
    return storeCollection.snapshots().map(_storeListfromSnapshot);
  }
}
question from:https://stackoverflow.com/questions/66066250/flutter-firebase-use-a-provider-only-locally-for-a-single-page

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...