将文档中的值从数据库保存到 initState 值的颤振问题

Posted

技术标签:

【中文标题】将文档中的值从数据库保存到 initState 值的颤振问题【英文标题】:Flutter problem with saving the value from document from database to a initState value 【发布时间】:2021-05-06 22:33:28 【问题描述】:

我在从数据库文档中获取值到 initState 方法中调用的变量时遇到问题。当我这样做时,空值存在问题,我认为 Firebase 的 get() 方法获取值太晚了(当我重新加载场景时会发生这种情况)。

  bool _dark;
  bool options;
  MainModel model;
  final MyUser myUser;
  final UserSettings userSettings;

  _SettingsOnePageState(this.userSettings, this.myUser);

  final user = FirebaseAuth.instance.currentUser;
  @override
  void initState() 
    super.initState();
    // _dark = false;
    FirebaseFirestore.instance
        .collection("settings")
        .doc(user.uid)
        .get()
        .then((value) 
      print(value.data()['darkMode']);
      _dark = value.data()['darkMode'];
    );
    options = false;
  

  Brightness _getBrightness() 
    return _dark ? Brightness.dark : Brightness.light;
  

@override
  Widget build(BuildContext context) 
    return Theme(
        // return StreamProvider<QuerySnapshot>.value(
        isMaterialAppTheme: true,
        data: ThemeData(
          brightness: _getBrightness(),
        ),
        // value: SettingsUser().settings,
        child: StreamBuilder<UserSettings>(
            //setting the stream for settings from database
            stream: DatabaseUser(userId: user.uid).userData,
            builder: (context, snapshot) 
              if (snapshot.hasData) 
                //data for user from database
                UserSettings userSettings = snapshot.data;
                // _dark = userSettings.darkMode;
                // print("dark mode " + userSettings.darkMode.toString());
                return Form(
                    key: _formKey,
                    child: Scaffold(
                        backgroundColor: _dark ? null : Colors.grey.shade200,
                        appBar: AppBar(
                          //elevation: 10,
                          brightness: _getBrightness(),
                          iconTheme: IconThemeData(
                              color: _dark ? Colors.white : Colors.black),
                          backgroundColor: Colors.transparent,
                          title: Text(
                            'Change theme',
                            style: TextStyle(
                                color: _dark ? Colors.white : Colors.black),
                            textAlign: TextAlign.center,
                          ),
                          actions: <Widget>[
                            IconButton(
                              icon: Icon(Icons.auto_awesome),
                              onPressed: () 
                                setState(() 
                                  _dark = !_dark;
                                );
                              ,
                            )
                          ],
                        ),
                        body: Stack(fit: StackFit.expand, children: <Widget>[
                          SingleChildScrollView(
                              //padding: const EdgeInsets.all(16.0),
                              child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                Stack(
                                  children: <Widget>[
                                    Align(
                                        alignment: Alignment.center,
                                        child: Text(
                                          userSettings.nick,
                                          textScaleFactor: 4,
                                          style: TextStyle(
                                            color: _dark
                                                ? Colors.white
                                                : Colors.purple[500],
                                            //fontWeight: FontWeight.w500,
                                          ),
                                        )),
                                    const SizedBox(height: 50.0),
                                  ],
                                ),
                                Stack(
                                  children: <Widget>[
                                    Align(
                                      alignment: Alignment.center,
                                      child: Container(
                                        // width: 200,
                                        // height: 200,
                                        child: CircleAvatar(
                                          radius: 100.0,
                                          backgroundImage:
                                              //NetworkImage(user.photoURL),
                                              NetworkImage(
                                                  userSettings.pictureUrl),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                                //const SizedBox(height: 20.0),
                                if (options == true) ...[
                                  //SettingsEdit(),
                                  //NickChange(),
                                  ImageInput(),
                                ],
                                const SizedBox(height: 10.0),
                                Card(
                                  elevation: 4.0,
                                  margin: const EdgeInsets.fromLTRB(
                                      32.0, 8.0, 32.0, 16.0),
                                  shape: RoundedRectangleBorder(
                                      borderRadius:
                                          BorderRadius.circular(10.0)),
                                  child: Column(
                                    children: <Widget>[
                                      ListTile(
                                        leading: Icon(
                                          Icons.account_box,
                                          color: Colors.purple,
                                        ),
                                        title: Text("Change Nickname"),
                                        trailing:
                                            Icon(Icons.keyboard_arrow_right),
                                        onTap: () 
                                          //open change nick
                                          //changeNick();
                                        ,
                                      ),
                                      _buildDivider(),
                                      ListTile(
                                        leading: Icon(
                                          Icons.add_a_photo,
                                          color: Colors.purple,
                                        ),
                                        title: Text("Change Photo"),
                                        trailing:
                                            Icon(Icons.keyboard_arrow_right),
                                        onTap: () 
                                          //open change photo
                                          //changePhoto();
                                        ,
                                      ),
                                      _buildDivider(),
                                      ListTile(
                                        leading: Icon(
                                          Icons.lock_rounded,
                                          color: Colors.purple,
                                        ),
                                        title: Text("Change Password"),
                                        trailing:
                                            Icon(Icons.keyboard_arrow_right),
                                        onTap: () 
                                          //open change password
                                          //changePassword();
                                        ,
                                      ),
                                      _buildDivider(),
                                      ListTile(
                                        leading: Icon(
                                          Icons.location_on,
                                          color: Colors.purple,
                                        ),
                                        title: Text("Change Your Location"),
                                        trailing:
                                            Icon(Icons.keyboard_arrow_right),
                                        onTap: () 
                                          //open change location
                                        ,
                                      ),
                                    ],
                                  ),
                                ),
                                const SizedBox(height: 20.0),
                              ]))
                        ])));
              
              return Scaffold();
            ));
  

debug console settings where I use theme now

你知道如何在 initState 中避免这个 null 吗?我正在尝试更改应用程序的主题,并从用户注册时创建的 Firebase 文档中获取该主题。比我将在用户设置中更改它并且还想在整个应用程序中使用它(这个主题)。 感谢您的帮助

【问题讨论】:

【参考方案1】:

InitState 不是异步的(意味着执行不会等待您的 firebase 调用完成)。这意味着您的视图将在您分配 _dark 值之前呈现。

如果您想等到该调用完成,请使用名为 FutureBuilder 的名称。

【讨论】:

以上是关于将文档中的值从数据库保存到 initState 值的颤振问题的主要内容,如果未能解决你的问题,请参考以下文章

将 Oracle 10g 中的值从表单 1 传递到表单 2 并将另一个值从表单 2 返回到表单 1 是不是可能

Filenet - 将值从工作项复制到文档属性

如何将 IBOutlet 值从视图传递到 VIPER iOs 中的交互器?

Foxpro / SQL复制值从游标到表的id匹配

将 Excel 中的值从字符串更改为数字

将下拉列表中的值从一个 php 传递到另一个