Flutter:Firebase 如何更改查询和内容

Posted

技术标签:

【中文标题】Flutter:Firebase 如何更改查询和内容【英文标题】:Flutter: Firebase How to change the query and the content 【发布时间】:2019-03-09 20:07:07 【问题描述】:

我正在尝试根据所选社区更改查询。

当您选择社区时,您必须显示该社区的内​​容。

我找到了一个解决方案,但我认为它不是正确的,因为该应用程序有 39 个国家/地区。

这 39 个要求你对每一个都有一个查询,并且有很多行代码。

我希望有比我发现的更好的解决方案。

GIF APP - 出现的错误是因为没有其他国家。

SearchClub.dart

这是返回与国家/地区相关的查询的函数。

我想使用一个,而不是针对每个国家/地区进行多次查询。

searchClubs(TextEditingController countryChanged) 
        var widgetFireUpdate;
        setState(() 
            if(countryChanged.text == 'SPAIN') 
              widgetFireUpdate = new FirebaseAnimatedList(
                query: FirebaseDatabase.instance.reference().child(widget.player.platform).child("CLUB").orderByChild('country').equalTo(countryChanged.text),
                sort: (a, b) => a.value['createdDate'].compareTo(b.value['createdDate']),
                reverse: true,
                shrinkWrap: true,
                defaultChild: new CircularProgressIndicator(),
                itemBuilder: (BuildContext context, DataSnapshot snapshot,
                    Animation<double> animation, int index) 
                  return new StreamBuilder<Event>(
                    stream: itemRef2.orderByKey().onValue,
                    builder: (context, AsyncSnapshot<Event> snapshot2)
                      if(snapshot2.hasData) 
                        try 
                          return new Container(
                            decoration: new BoxDecoration(
                              color: Colors.grey[300],
                            ),
                            child: new ListTile(
                                leading: snapshot.value['logoURL'].toString().indexOf('images/assets/logo_notfound.png') == -1 ? new CachedNetworkImage(imageUrl: snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8) : new Image.asset(snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8),
                                title: new Text(snapshot.value['name'].toUpperCase(), style: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: MediaQuery.of(context).size.width/30)),
                                subtitle: new RichText(
                                  text: new TextSpan(
                                      children: <TextSpan>[
                                        new TextSpan(text: "CAPITÁN:", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35, fontWeight: FontWeight.bold)),
                                        new TextSpan(text: " $snapshot.value['captain'].toUpperCase()", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35)),
                                      ]
                                  ),
                                ),
                            ),
                          );

                        catch(e) 
                          return new Container();
                        
                       else if(snapshot2.hasError)
                        return new Container();
                       else 
                        return new Container(
                          child: new Center(
                            child: new CircularProgressIndicator(
                              backgroundColor: Colors.red,
                            ),
                          ),
                        );
                      
                    ,
                  );
                ,
              );
             else if(countryChanged.text == 'BRAZIL') 
              widgetFireUpdate = new FirebaseAnimatedList(
                query: FirebaseDatabase.instance.reference().child(widget.player.platform).child("CLUB").orderByChild('country').equalTo(countryChanged.text),
                sort: (a, b) => a.value['createdDate'].compareTo(b.value['createdDate']),
                reverse: true,
                shrinkWrap: true,
                defaultChild: new CircularProgressIndicator(),
                itemBuilder: (BuildContext context, DataSnapshot snapshot,
                    Animation<double> animation, int index) 
                  return new StreamBuilder<Event>(
                    stream: itemRef2.orderByKey().onValue,
                    builder: (context, AsyncSnapshot<Event> snapshot2)
                      if(snapshot2.hasData) 
                        try 
                          return new Container(
                            decoration: new BoxDecoration(
                              color: Colors.grey[300],
                            ),
                            child: new ListTile(
                              leading: snapshot.value['logoURL'].toString().indexOf('images/assets/logo_notfound.png') == -1 ? new CachedNetworkImage(imageUrl: snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8) : new Image.asset(snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8),
                              title: new Text(snapshot.value['name'].toUpperCase(), style: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: MediaQuery.of(context).size.width/30)),
                              subtitle: new RichText(
                                text: new TextSpan(
                                    children: <TextSpan>[
                                      new TextSpan(text: "CAPITÁN:", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35, fontWeight: FontWeight.bold)),
                                      new TextSpan(text: " $snapshot.value['captain'].toUpperCase()", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35)),
                                    ]
                                ),
                              ),
                            ),
                          );

                        catch(e) 
                          return new Container();
                        
                       else if(snapshot2.hasError)
                        return new Container();
                       else 
                        return new Container(
                          child: new Center(
                            child: new CircularProgressIndicator(
                              backgroundColor: Colors.red,
                            ),
                          ),
                        );
                      
                    ,
                  );
                ,
              );
            
        );
        return widgetFireUpdate;
      


  // OPEN LIST COMMUNITY
  Widget _buildBottomPicker() 
    final FixedExtentScrollController scrollController = new FixedExtentScrollController();
    return new Container(
      height: MediaQuery.of(context).size.height/3.5,
      color: CupertinoColors.white,
      child: new DefaultTextStyle(
        style: const TextStyle(
          color: CupertinoColors.black,
          fontSize: 22.0,
        ),
        child: new SafeArea(
          child: new CupertinoPicker(
            scrollController: scrollController,
            itemExtent: MediaQuery.of(context).size.height/15,
            magnification: 0.7,
            diameterRatio: 0.5,
            backgroundColor: CupertinoColors.white,
            onSelectedItemChanged: (int index) 
              setState(() 
                _comunidad.text = _comunidades[index];
                _imgComunidad = _imgComunidades[index];
              );
            ,
            children: new List<Widget>.generate(_comunidades.length, (int index) 
              return new Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Text(_comunidades[index]),
                ],
              );
            ),
          ),
        ),
      ),
    );
  


@override
  Widget build(BuildContext context) 
    return new Scaffold(
      key: _scaffoldKey,
      appBar: searchBar.build(context),
      body: new Container(
        color: widget.themeConsole,
        child: new Column(
          children: <Widget>[
            new Card(
              elevation: 0.0,
              color: Colors.grey[50],
              child: new Container(
                child: new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new Container(
                      width: MediaQuery.of(context).size.width/1.35,
                      child: new TextFormField(
                        controller: _comunidad,
                        style: new TextStyle(color: Colors.white),
                        enabled: false,
                        decoration: new InputDecoration(
                          labelText: 'Community:',
                          labelStyle: new TextStyle(color: Colors.white),
                          icon: new Image.asset(_imgComunidad, width: 24.0),
                          filled: true,
                          fillColor: Colors.grey[800],
                        ),
                        validator: (String value)
                          player.country = value;
                        ,
                      ),
                    ),
                    new IconButton(
                      icon: new Icon(Icons.flag, color: Colors.grey[800], size: 30.0,),
                      color: Colors.black,
                      onPressed: ()async 
                        await showModalBottomSheet<void>(
                          context: context,
                          builder: (BuildContext context) 
                            return _buildBottomPicker();
                          ,
                        );
                      ,
                    ),
                  ],
                ),
              ),
            ),
            new Flexible(child: searchClubs(_comunidad))
          ],
        )
      ),
    );
  

SearchClub 完成:https://pastebin.com/zbeU6M1u

【问题讨论】:

也许这可以帮助你:***.com/a/53896108/2831595,我只是不确定是否正确,但它对我有用。 【参考方案1】:

据我了解,您正在使用 firebase 实时数据库,其中您的子名称为国家/地区,并且该节点内有数据。您希望以这样一种方式进行查询,即当您选择一个国家/地区时,该特定查询应该像选择阿根廷时一样进行,您的数据库中阿根廷内的所有内容都应该被调用。

将国家/地区名称的值存储在列表中,并为调用国家/地区创建一个字符串。

String country="";
List<String> country_name=["Argentina","Brazil","Spain"....];

现在按功能可以这样-

onPressed: () 
                    setState(() 
                      country=country_name[1];//example
                    );
                    country_call();
                  

这将在我们更改国家/地区名称时帮助我们。

最后在您的 firebase 参考中进行更改-

Future<void> country_call()async

    final FirebaseDatabase database = FirebaseDatabase().instance();
   setState(() 
     itemRef = database.reference().child(country);
     itemRef.onChildAdded.listen(_onEntryAdded);
     itemRef.onChildChanged.listen(_onEntryChanged);
   );
  

通过更改,您无需为 39 个不同的国家/地区编写代码即可调用不同的查询。如果您使用列表视图来显示我们的数据,请确保在 country_call 函数中将其清空。这可以通过简单地将其等同于 null list("[]") 来完成。

我正在寻找类似的东西,但在网站上找不到任何东西。我使用这种方法来解决我的问题。希望对你也有帮助。

【讨论】:

以上是关于Flutter:Firebase 如何更改查询和内容的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:如何在 [Firebase] 中使用 OR 条件获取流查询

Flutter-如何在firebase查询中使用逻辑AND以及如何更新数据?

在 Flutter 中记录 Firebase 查询

Flutter:数据更改时的 Firebase 推送通知

如何在项目中使用 firebase 和 firebase 功能的现有 Flutter 应用程序中更新包名称?

如何在flutter中从firebase实时数据库中获取数据?