flutter - 使用Future时无法将值存储到Flutter/Dart中的类变量

标签 flutter dart

我想将共享首选项的值存储在类变量中,但是它根本不起作用,该值也不存储到变量中。
这是我的代码,基本上我想存储到变量_uid,但是当我在自己的UI中访问它时,它会打印“”。

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class User with ChangeNotifier {
  FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  Firestore _firestore = Firestore.instance;
  bool _loggedIn = false;
  bool get loggedIn => _loggedIn;
  String _uid = "";
  String get uid => _uid;
  User() {
    getPrefState().then((val) {
      // do some operation
      _uid = val.toString() ?? "test";
    });
    
    //init();
  }
  Future init() async {
    //var data;
    //_uid = getPrefState();
    /*SharedPreferences.getInstance().then((value) => {
          _uid = value.getString("uid") ?? "d",
          data = "dsdasd",
        });*/
    /*try {
      SharedPreferences prefs = await SharedPreferences.getInstance();

      _uid = data;
    } catch (err) {
      //pass.
    }*/

    //var uid = prefs.getString("uid") ?? "d";
    /*if (uid != null) {
      _loggedIn = true;
    }*/
    //_uid = "dsd";
    //notifyListeners();
  }

  Future<String> getPrefState() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    //Return String
    String stringValue = prefs.getString('uid') ?? "test";
    return stringValue;
  }

  Future<void> saveId(uid) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString("uid", uid);
  }

  Future<void> saveUserInDocument(String uid, String name, String sap) {
    _firestore.collection("users").document(uid).setData({
      "name": name,
      "sap": sap,
      'role': "student",
    });
  }

  Future<FirebaseUser> getCurrentUser() async {
    return await _firebaseAuth.currentUser();
  }

  // user signup.
  Future<void> signup(
      String email, String password, String name, String sap) async {
    FirebaseUser user = (await _firebaseAuth.createUserWithEmailAndPassword(
            email: email, password: password))
        .user;
    if (user != null) {
      saveUserInDocument(user.uid, name, sap);
      saveId(user.uid);
      _loggedIn = true;
      notifyListeners();
    }
  }

  /// user login
  Future<void> login(String email, String password) async {
    FirebaseUser user = (await _firebaseAuth.signInWithEmailAndPassword(
            email: email, password: password))
        .user;
    //if (user != null) {
    saveId(user.uid);
    _loggedIn = true;
    notifyListeners();
    //}
  }

  /// User logout
  Future<void> logout() async {
    _firebaseAuth.signOut();
    saveId(null);
    _loggedIn = false;
    notifyListeners();
  }

  /// reset user password
  Future<void> resetPassword(String email) async {
    await _firebaseAuth.sendPasswordResetEmail(email: email);
  }
}
这是我要使用的UI类user.uid
import "package:flutter/material.dart";
import 'package:riphahwebresources/data/User.dart';
import 'package:riphahwebresources/pages/auth/login_ui.dart';
import 'package:shared_preferences/shared_preferences.dart';

class WebResourceAppDrawer extends StatefulWidget {
  @override
  _WebResourceAppDrawerState createState() => _WebResourceAppDrawerState();
}

class _WebResourceAppDrawerState extends State<WebResourceAppDrawer> {
  User user = User();

  @override
  Widget build(BuildContext context) {
    List<Widget> children = [];
    children.add(
      ListTile(
        leading: Icon(Icons.home),
        title: Text("Home"),
      ),
    );
    if (user.loggedIn) {
      children.add(ListTile(
        leading: Icon(Icons.people),
        title: Text("Profile"),
        onTap: () => {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => LoginUi()))
        },
      ));
      children.add(ListTile(
        leading: Icon(Icons.people),
        title: Text("Logout"),
        onTap: () => {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => LoginUi()))
        },
      ));
    } else {
      children.add(ListTile(
        leading: Icon(Icons.people),
        title: Text(user.uid),
        onTap: () => {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => LoginUi()))
        },
      ));
    }
    return Drawer(
      child: ListView(
        padding: const EdgeInsets.all(8),
        children: <Widget>[
          DrawerHeader(
            child: Text("Menu"),
          ),
          ...children,
        ],
      ),
    );
  }
}
您可以从init方法中看到我尝试了不同的方法,但idk对我没有用。
非常感谢。

最佳答案

使用ChangeNotifier时,您需要调用notifyListeners将更改传播到您的UI类:

notifyListeners(). Call this method any time the model changes in a way that might change your app’s UI.


Flutter Docs on State Management
提醒一下,要使State Management正常工作,您需要执行以下三件事:
  • 设置一个extends ChangeNotifier的类(您已经完成了,只不过将with替换为extends)
  • 在小部件上方的需要该值的小部件(即ChangeNotifierProvider UI小部件上方)添加WebResourceAppDrawer
  • 现在通过使用User包装您的UI小部件来访问Consumer<User>

  • 这是一个完整的最小示例:
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
              body: Center(
                  child:
                      ChangeNotifierProvider(create: (_) => User(), child: UI()))),
                      // 'UI' can now access the newly created User() since it's a
                      // child of ChangeNotifierProvider
        );
      }
    }
    
    class UI extends StatefulWidget {
      @override
      _UIState createState() => _UIState();
    }
    
    class _UIState extends State<UI> {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Consumer<User>(
              builder: (context, user, child) => Text("User ${user.uid}")),
              // This is how user can be accessed within UI
        );
      }
    }
    
    class User extends ChangeNotifier {
      String _uid = "(empty)";
      String get uid => _uid;
    
      User() {
        getPrefState().then((val) {
          _uid = val;
          notifyListeners(); // this call triggers a rebuild of UI
        });
      }
    
      getPrefState() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        return prefs.getString('uid');
      }
    }
    

    关于flutter - 使用Future时无法将值存储到Flutter/Dart中的类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64098166/

    相关文章:

    flutter 安装不起作用?

    Flutter 为 Web 构建 - "Failed to compile application"

    list - 在包含特定名称的列表中显示项目 - flutter

    Flutter - ParentDataWidget 的不正确使用

    generics - 使用带有泛型的 Dart 的 call() 方法

    android - 为什么Flutter导入提供程序包不起作用?

    flutter - 如何在没有 firebase 或一个信号的情况下用 flutter 从后端推送通知?

    flutter - 当 Flutter Widget 的属性发生变化时,它的重新渲染是如何工作的?

    flutter - TextField - 聚焦

    flutter - 如何在单击文本字段时强制屏幕向下滚动?