【问题标题】:Flutter: Firebase basic Query or Basic Search codeFlutter:Firebase 基本查询或基本搜索代码
【发布时间】:2018-11-25 00:12:13
【问题描述】:

主要概念是显示包含搜索字母的文档或字段。

搜索栏得到给定的输入,它发送到_firebasesearch(),但没有返回任何东西,上图是我的数据库结构,试图弄清楚一个多星期。

代码

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_search_bar/flutter_search_bar.dart';

SearchBar searchBar;
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

class DisplayCourse extends StatefulWidget {
  @override
  _DisplayCourseState createState() => new _DisplayCourseState();
}

AppBar _buildAppBar(BuildContext context) {
  return new AppBar(
    title: new Text("FIREBASE QUERY"),
    centerTitle: true,
    actions: <Widget>[
      searchBar.getSearchAction(context),
    ],
  );
}

class _DisplayCourseState extends State<DisplayCourse> {
  String _queryText;

  _DisplayCourseState() {
    searchBar = new SearchBar(
      onSubmitted: onSubmitted,
      inBar: true,
      buildDefaultAppBar: _buildAppBar,
      setState: setState,
    );
  }

  void onSubmitted(String value) {
    setState(() {
      _queryText = value;
      _scaffoldKey.currentState.showSnackBar(new SnackBar(
        content: new Text('You have Searched something!'),
        backgroundColor: Colors.yellow,
      ));
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: _scaffoldKey,
      appBar: searchBar.build(context),
      backgroundColor: Colors.red,
      body: _fireSearch(_queryText),
    );
  }
}

Widget _fireSearch(String queryText) {
  return new StreamBuilder(
    stream: Firestore.instance
    .collection('courses')
    .where('title', isEqualTo: queryText)
    .snapshots(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) return new Text('Loading...');
      return new ListView.builder(
        itemCount: snapshot.data.documents.length,
        itemBuilder: (context, index) =>
            _buildListItem(snapshot.data.documents[index]),
      );
    },
  );
}

Widget _buildListItem(DocumentSnapshot document) {
  return new ListTile(
    title: document['title'],
    subtitle: document['subtitle'],
  );
}

主要概念是显示包含搜索字母的文档或字段

搜索栏得到给定的输入,它发送到_firebasesearch(),但作为回报没有任何结果,上图是我的数据库结构,试图弄清楚一个多星期,

【问题讨论】:

  • 正确地格式化代码使得人们更有可能真正尝试理解它。应该不会太难。
  • 您是在搜索栏中提供完整的标题,如new program,还是只是标题的一部分?
  • @VinothKumar "new" 够了兄弟,我不会搜索全文
  • @VinothKumar 我听不懂兄弟,只是新手
  • 我认为我们现在不能查询部分文本

标签: firebase-realtime-database dart google-cloud-firestore flutter flutter-dependencies


【解决方案1】:

这听起来可能是一个荒谬的解决方案,但实际上效果很好,几乎就像 SQL 中的 Like '%' 查询

在 TextField 中,当您在 where() isGreaterThanOrEqualTowill 中输入一个值时,将其与所有大于输入的字符串值进行比较,如果您连接一个“Z” 最后,isLessThan 将在您的搜索关键字之后结束,您会从 firestore 获得所需的结果。

// Declare your searchkey and Stream variables first
String searchKey;
Stream streamQuery;

TextField(
              onChanged: (value){
                  setState(() {
                    searchKey = value;
                    streamQuery = _firestore.collection('Col-Name')
                        .where('fieldName', isGreaterThanOrEqualTo: searchKey)
                        .where('fieldName', isLessThan: searchKey +'z')
                        .snapshots();
                  });
    }),

我在 StreamBuilder 中使用了这个 Stream,它的工作原理完全符合预期。

限制:

  1. 搜索区分大小写(如果您的数据与 Type Case 一样,您可以将 searchKey 转换为特定大小写)
  2. 你必须从第一个字母开始搜索,不能从中间开始搜索

【讨论】:

  • 伙计,我已经尝试解决这个问题大约一个星期了,我无法用任何语言来形容你解决这个问题的能力有多棒
  • @James666 谢谢,很高兴我能提供帮助。正是这样的 cmets 让我们有动力分享越来越多的东西。希望您投票并与社区分享您的知识。
【解决方案2】:

我有点晚了,但我只想分享一些关于我如何在不使用第三方应用程序的情况下实现搜索功能的内容。我的解决方案是使用 firestore 进行一些直接的查询。代码如下:

Future<List<DocumentSnapshot>> getSuggestion(String suggestion) =>
  Firestore.instance
      .collection('your-collection')
      .orderBy('your-document')
      .startAt([searchkey])
      .endAt([searchkey + '\uf8ff'])
      .getDocuments()
      .then((snapshot) {
        return snapshot.documents;
      });

例如,如果您要搜索所有包含“ab”的关键字,那么它将显示所有包含“ab”的单词(例如 abcd、abde、abwe)。如果您想制作自动建议搜索功能,您可以使用 typehead。可以在这个链接中找到:https://pub.dev/packages/flutter_typeahead

祝你好运。

【讨论】:

  • 我们可以让它不区分大小写吗??
  • 嗨@Mahi,就目前而言,我目前的解决方案是自动小写保存的文本并自动小写搜索表单。例子。关键字是:“面包”,然后自动添加另一个字段“面包”,用于搜索关键字。
  • 我现在也在做同样的事情。不知道firebase是否会支持该功能,因为我认为mongoDB拥有它。
  • orderBy("") 是必须的,否则它会给你错误 Firebase 错误 - 提供的参数太多。
【解决方案3】:

您不必重建整个流,只需根据搜索字符串过滤流中的结果即可。 快速,不需要重建整个流,不仅从单词的开头查找搜索字符串的出现,而且不区分大小写。

return StreamBuilder(
  stream: FirebaseFirestore.instance.collection("shops").snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {

    if (snapshot.hasError)  // TODO: show alert
      return Text('Something went wrong');

    if (snapshot.connectionState == ConnectionState.waiting)
      return Column(
        children: [
          Center(
              child: CupertinoActivityIndicator()
          )
        ],
      );

    var len = snapshot.data.docs.length;
    if(len == 0)
      return Column(
        children: [
          SizedBox(height: 100),
          Center(
            child: Text("No shops available", style: TextStyle(fontSize: 20, color: Colors.grey)),
          )
        ],
      );

    List<Shop> shops = snapshot.data.docs.map((doc) => Shop(
        shopID: doc['shopID'],
        name: doc['name'],
        ...
    )).toList();
    shops = shops.where((s) => s.name.toLowerCase().contains(searchString.text.toLowerCase())).toList();
    
    
    return
        Expanded(
          child: ListView.builder(
              padding: EdgeInsets.symmetric(vertical: 15),
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: shops.length,
              itemBuilder: (context, index) {
                return shopRow(shops[index]);
              }
          ),
        );
  },
);

【讨论】:

    【解决方案4】:

    问题是您期望来自 title is equal to queryText 而不是 title contains queryText 的 firestore 的结果。

    如果您想要搜索功能,您可以在变量中使用get and store the firestore documents,例如List&lt;Model&gt; model,而不是上面存储的模型列表中的StreamBuilderimplement search manually

    【讨论】:

      【解决方案5】:

      这是另一个搜索代码,它将在 FIREBASE 数据库中搜索

      import 'package:flutter/material.dart';
      import 'package:firebase_database/firebase_database.dart';
      import 'package:firebase_database/ui/firebase_animated_list.dart';
      
      class Db extends StatefulWidget {
        @override
        HomeState createState() => HomeState();
      }
      
      class HomeState extends State<Db> {
        List<Item> Remedios = List();
        Item item;
        DatabaseReference itemRef;
        TextEditingController controller = new TextEditingController();
        String filter;
      
        final GlobalKey<FormState> formKey = GlobalKey<FormState>();
      
        @override
        void initState() {
          super.initState();
          item = Item("", "");
          final FirebaseDatabase database = FirebaseDatabase.instance; //Rather then just writing FirebaseDatabase(), get the instance.
          itemRef = database.reference().child('Remedios');
          itemRef.onChildAdded.listen(_onEntryAdded);
          itemRef.onChildChanged.listen(_onEntryChanged);
          controller.addListener(() {
        setState(() {
          filter = controller.text;
        });
      });
        }
      
        _onEntryAdded(Event event) {
          setState(() {
            Remedios.add(Item.fromSnapshot(event.snapshot));
          });
        }
      
        _onEntryChanged(Event event) {
          var old = Remedios.singleWhere((entry) {
            return entry.key == event.snapshot.key;
          });
          setState(() {
            Remedios\[Remedios.indexOf(old)\] = Item.fromSnapshot(event.snapshot);
          });
        }
      
        void handleSubmit() {
          final FormState form = formKey.currentState;
      
          if (form.validate()) {
            form.save();
            form.reset();
            itemRef.push().set(item.toJson());
          }
        }
      
        @override
        void dispose() {
          controller.dispose();
          super.dispose();
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: new AppBar(
              centerTitle: true,
              backgroundColor: new Color(0xFFE1564B),
            ),
            resizeToAvoidBottomPadding: false,
            body: Column(
              children: <Widget>\[
                new TextField(
                decoration: new InputDecoration(
                labelText: "Type something"
                ),
                controller: controller,
                ),
                Flexible(
                  child: FirebaseAnimatedList(
                    query: itemRef,
                    itemBuilder: (BuildContext context, DataSnapshot snapshot,
                        Animation<double> animation, int index) {
                      return  Remedios\[index\].name.contains(filter) || Remedios\[index\].form.contains(filter) ? ListTile(
                        leading: Icon(Icons.message),
                        title: Text(Remedios\[index\].name),
                        subtitle: Text(Remedios\[index\].form),
                      ) : new Container();
                    },
                  ),
                ),
              \],
            ),
          );
        }
      }
      
      class Item {
        String key;
        String form;
        String name;
      
        Item(this.form, this.name);
      
        Item.fromSnapshot(DataSnapshot snapshot)
            : key = snapshot.key,
              form = snapshot.value\["form"\],
              name = snapshot.value\["name"\];
      
        toJson() {
          return {
            "form": form,
            "name": name,
          };
        }
      }
      

      【讨论】:

      • 能否分享一下 github 仓库,以便我们克隆代码并运行它?
      • @biniam 对不起,这是我的旧帖子,上面的方法太愚蠢了,以至于 firebase/firestore 都不是为搜索而设计的,而我在上面所做的是,检索了所有孩子里面的孩子,只显示包含 tyepd 关键字的特定文档,[我现在不推荐该方法] 抱歉!!
      • @biniam 目前还没有可用于 firestore 和 firebase 的适当文本搜索,但您可以使用 Algolia,查看 RajaYogan Youtube 频道上的教程 >youtube.com/channel/UCjBxAm226XZvgrkO-JyjJgQ(或)Samrath agarwal youtube 频道 > @987654323 @
      • @HussnainHaidar 它的工具旧帖子和搜索本身尚未实现,顺便说一句,您提供的方法完全是付款的杀手。
      【解决方案6】:

      我找到的解决方案:

      List<String> listaProcura = List();
          String temp = "";
          for(var i=0;i<nomeProduto.length; i++) {
            if(nomeProduto[i] == " ") {
              temp = "";
            } else {
              temp = temp + nomeProduto[i];
              listaProcura.add(temp);
            }
          }
      

      “listaProcura”是列表的名称。 字符串“temp”是临时字符串的名称。 这样,您将在 firebase 数据库中保存此名称列表。 会是这样的:

        [0] E
        [1] Ex
        [2] Exa
        [3] Exam
        [4] Examp
        [5] Exampl
        [6] Example
        [7] o
        [8] on
        [9] one
      

      使用您要搜索的词检索此信息:

      await Firestore.instance.collection('name of your collection').where('name of your list saved in the firebase', arrayContains: 'the name you are searching').getDocuments();
      

      这样,如果您搜索“one”并且名称为“Example one”,搜索将正确返回。

      【讨论】:

      • 您好,先生,您有与此相关的示例代码
      【解决方案7】:

      如果搜索列表像这样区分大小写:

      1. Curaprox 为您展示
      2. Curaprox 黑是白显示器
      3. Curaprox Black is White Mini Display
      4. Curaprox Hydrosonic Pro 显示器
      5. Curaprox 大型齿间刷展示架

      然后:

                      response = await FirebaseFirestore.instance
                      .collection('pointOFSale')
                      .orderBy("title")
                      .startAt([val.capitalize()]).endAt(
                          [val[0].toUpperCase() + '\uf8ff']).get();
      

      扩展代码:

                extension StringExtension on String {
              String capitalize() {
                return "${this[0].toUpperCase()}${this.substring(1)}";
              }
            }
      

      如果列表是这样的:

      1. curaprox 是你显示的
      2. curaprox black is white display
      3. curaprox black is white mini display

      然后:

                      response = await FirebaseFirestore.instance
                      .collection('pointOFSale')
                      .orderBy("title")
                      .startAt([val]).endAt([val + '\uf8ff']).get();
      

      【讨论】:

        【解决方案8】:

        如此简单和快速。

        if (text.length > 1) {
          setState(() {
            tempSearchStore = _listPkh.documents.where((d) {
              if (d['nama'].toLowerCase().indexOf(text) > -1) {
                return true;
              } else if (d['alamat'].toLowerCase().indexOf(text) > -1) {
                return true;
              }
              return false;
            }).toList();
          });
        } else {
          setState(() {
            tempSearchStore = _listPkh.documents;
          });
        }
        

        【讨论】:

          猜你喜欢
          • 2019-08-11
          • 1970-01-01
          • 2010-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-06
          • 1970-01-01
          相关资源
          最近更新 更多