Flutter - How to pass user data to all views

前端 未结 5 627
醉酒成梦
醉酒成梦 2021-01-30 03:10

I\'m new to the flutter world and mobile app development and struggling with how I should pass user data throughout my app.

I\'ve tried several things, but none seem gre

相关标签:
5条回答
  • 2021-01-30 03:44

    I'd recommend investigating inherited widgets further; the code below shows how to use them with asynchronously updating data:

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    
    void main() {
      runApp(new MaterialApp(
          title: 'Inherited Widgets Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new Scaffold(
              appBar: new AppBar(
                title: new Text('Inherited Widget Example'),
              ),
              body: new NamePage())));
    }
    
    // Inherited widget for managing a name
    class NameInheritedWidget extends InheritedWidget {
      const NameInheritedWidget({
        Key key,
        this.name,
        Widget child}) : super(key: key, child: child);
    
      final String name;
    
      @override
      bool updateShouldNotify(NameInheritedWidget old) {
        print('In updateShouldNotify');
        return name != old.name;
      }
    
      static NameInheritedWidget of(BuildContext context) {
        // You could also just directly return the name here
        // as there's only one field
        return context.inheritFromWidgetOfExactType(NameInheritedWidget);
      }
    }
    
    // Stateful widget for managing name data
    class NamePage extends StatefulWidget {
      @override
      _NamePageState createState() => new _NamePageState();
    }
    
    // State for managing fetching name data over HTTP
    class _NamePageState extends State<NamePage> {
      String name = 'Placeholder';
    
      // Fetch a name asynchonously over HTTP
      _get() async {
        var res = await http.get('https://jsonplaceholder.typicode.com/users');
        var name = json.decode(res.body)[0]['name'];
        setState(() => this.name = name); 
      }
    
      @override
      void initState() {
        super.initState();
        _get();
      }
    
      @override
      Widget build(BuildContext context) {
        return new NameInheritedWidget(
          name: name,
          child: const IntermediateWidget()
        );
      }
    }
    
    // Intermediate widget to show how inherited widgets
    // can propagate changes down the widget tree
    class IntermediateWidget extends StatelessWidget {
      // Using a const constructor makes the widget cacheable
      const IntermediateWidget();
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Padding(
            padding: new EdgeInsets.all(10.0),
            child: const NameWidget()));
      }
    }
    
    class NameWidget extends StatelessWidget {
      const NameWidget();
    
      @override
      Widget build(BuildContext context) {
        final inheritedWidget = NameInheritedWidget.of(context);
        return new Text(
          inheritedWidget.name,
          style: Theme.of(context).textTheme.display1,
        );
      }
    }
    
    0 讨论(0)
  • 2021-01-30 03:45

    You can use the GetX package to check whether or not the user is logged in, get user data and have it accessible throughout your app

    0 讨论(0)
  • 2021-01-30 03:49

    I crashed into another problem because of this problem you can check it out here So the solution I came up with is a bit untidy,I created a separate Instance dart page and imported it to every page.

     GoogleSignInAccount Guser = googleSignIn.currentUser;
     FirebaseUser Fuser;
    

    I stored the user there on login and checked on every StateWidget if it was null

      Future<Null> _ensureLoggedIn() async {
    
    if (Guser == null) Guser = await googleSignIn.signInSilently();
    if (Fuser == null) {
      await googleSignIn.signIn();
      analytics.logLogin();
    }
    if (await auth.currentUser() == null) {
      GoogleSignInAuthentication credentials =
      await googleSignIn.currentUser.authentication;
      await auth.signInWithGoogle(
        idToken: credentials.idToken,
        accessToken: credentials.accessToken,
      );
    }
    

    This is my old code I did cleaned it up on my current app but I don't have that code now in handy. Just check out for null user and log it in again

    I did it for most of the Firebase instances too because I have more than 3 pages on my app and Inherited Widgets was just too much work

    0 讨论(0)
  • 2021-01-30 03:52

    For my lazy mathod, i just create new file like userdata.dart and then put any variable on it for example like dynamic Profile = null

    inside userdata.dart

    //only put this or anything u want.
    dynamic Profile = null;
    

    at startingpage.dart

    //import that file
    import '../userdata.dart';
    
    class startingpage extends ...{
    ...
    //set data to store..
       Profile = 'user profile';
    ...
    }
    

    to use the data just declare and use in anotherpage.dart

    //import that file
    import '../userdata.dart';
    
    class anotherpage extends...{
    ...
    }
    
    class .. State ...{
    ...
    //set the data to variable
       dynamic userdata = Profile;
       print('this is my lazy pass data' + userdata.toString());
    ...
    }
    
    0 讨论(0)
  • 2021-01-30 04:04

    I prefer to use Services with Locator, using Flutter get_it.

    Create a UserService with a cached data if you like:

    class UserService {
      final Firestore _db = Firestore.instance;
      final String _collectionName = 'users';
      CollectionReference _ref;
    
      User _cachedUser; //<----- Cached Here
    
      UserService() {
        this._ref = _db.collection(_collectionName);
      }
    
      User getCachedUser() {
        return _cachedUser;
      }
    
      Future<User> getUser(String id) async {
        DocumentSnapshot doc = await _ref.document(id).get();
    
        if (!doc.exists) {
          log("UserService.getUser(): Empty companyID ($id)");
          return null;
        }
    
        _cachedUser = User.fromDocument(doc.data, doc.documentID);
        return _cachedUser;
      }
    }
    

    Then create create a Locator

    GetIt locator = GetIt.instance;
    
    void setupLocator() {
      locator.registerLazySingleton(() => new UserService());
    }
    

    And instantiate in main()

    void main() {
      setupLocator();
      new Routes();
    }
    

    That's it! You can call your Service + cachedData everywhere using:

    .....
    UserService _userService = locator<UserService>();
    
    @override
    void initState() {
      super.initState();
      _user = _userService.getCachedUser();
    }
    
    0 讨论(0)
提交回复
热议问题