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

标签 firebase firebase-realtime-database dart flutter

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

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

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

这39条要求你每一条都要查询,而且代码行很多。

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

动图应用 - 出现的错误是因为没有其他国家。 enter image description here

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

最佳答案

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

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

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 个不同的国家编写。如果您使用 ListView 来显示我们的数据,请确保在 country_call 函数中将其清空。这可以通过简单地将其等同于 null list("[]") 来完成。

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

关于firebase - Flutter:Firebase 如何更改查询和内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52646592/

相关文章:

javascript - Child_added 获取最后添加的项目 javascript

javascript - 从 Firebase 数据库加载数据并使用 JavaScript 放置在 map 的标记上

firebase - authClient.login 返回错误 "Unauthorized request origin"

list - 无法使用列表创建ListView.builder

java - Firebase 云功能( strip : AddPaymentSource)

java - 从 Firebase 按 ID 检索 Java 对象

java - 如何对数据求和并将其传输到 Firebase?

javascript - Firebase 警告 : Using an unspecified index when search data with Firebase Cloud Function

android - 在 flutter 应用程序中添加 image_picker 插件后,Gradle 构建失败

dart - Flutter - CustomPainter 中自下而上的动画