Flutter应用如何从Firebase实时数据库查询匹配当前日期的数据
Flutter 从Firebase实时数据库按日期筛选数据实现方案
核心实现逻辑
你要筛选和指定日期匹配的记录,只需要在现有排序查询的基础上追加equalTo匹配条件即可,具体实现如下:
1. 修改查询逻辑
在initState方法中,已经生成了和数据库date字段格式一致的today字符串,直接将其作为匹配条件传入查询即可:
@override void initState() { super.initState(); String today = formatter.format(now); _ref = FirebaseDatabase.instance .reference() .child('Daily Verse') .orderByChild('date') // 新增匹配条件,只返回date等于今日的记录 .equalTo(today); }
2. (可选)适配指定日期查询
如果需要查询非今日的其他日期,只需要给页面新增一个入参接收指定的DateTime,替换掉代码中的now变量即可:
class ReadPromise extends StatefulWidget { // 新增可选参数,不传默认查今日 final DateTime? targetDate; const ReadPromise({super.key, this.targetDate}); @override _ReadPromiseState createState() => _ReadPromiseState(); } class _ReadPromiseState extends State<ReadPromise> { // 替换原来的now变量 late final DateTime now = widget.targetDate ?? DateTime.now(); // 剩余代码保持不变 }
3. 配置数据库索引提升查询性能
当数据量较大时,为了避免查询报错、提升查询效率,需要在Firebase实时数据库的规则中为date字段配置索引:
{ "rules": { "Daily Verse": { ".indexOn": "date", // 剩余原有规则保持不变 } } }
注意事项
- 必须保证
DateFormat的输出格式和数据库中date字段的存储格式完全一致,包括月份拼写、大小写、空格、日期位数等,否则会出现匹配不到数据的问题 - 原代码中存在语法错误:
build方法结束后多了一个多余的闭合大括号,需要删除避免编译报错
修改后完整代码
import 'package:firebase_database/firebase_database.dart'; import 'package:firebase_database/ui/firebase_animated_list.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class ReadPromise extends StatefulWidget { final DateTime? targetDate; const ReadPromise({super.key, this.targetDate}); @override _ReadPromiseState createState() => _ReadPromiseState(); } class _ReadPromiseState extends State<ReadPromise> { late Query _ref; DatabaseReference reference = FirebaseDatabase.instance.reference().child('Daily Verse'); late final DateTime now = widget.targetDate ?? DateTime.now(); final DateFormat formatter = DateFormat("dd MMMM yyyy"); @override void initState() { super.initState(); String today = formatter.format(now); _ref = FirebaseDatabase.instance .reference() .child('Daily Verse') .orderByChild('date') .equalTo(today); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.indigo[900], title: const Text('Daily Promise Archive', textAlign: TextAlign.center,), ), body:Container( height: double.infinity, child: FirebaseAnimatedList( query: _ref, itemBuilder: (BuildContext context, DataSnapshot snapshot, Animation<double> animation, int index) { Map readVerse = snapshot.value as Map; readVerse['key'] = snapshot.key; return _buildContactItem(readPromise: readVerse); }) ) ); } Widget _buildContactItem({required Map readPromise}) { return Container( margin: const EdgeInsets.symmetric(vertical: 10), padding: const EdgeInsets.all(10), height: 130, color: Colors.white, child: Container( child: Card( color: Colors.indigo, shadowColor: Colors.black, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: const [ SizedBox( width: 6, ), Text( '内容', style: TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.bold), ), ], ), const SizedBox( height: 20, ), Row( children: [ const SizedBox( width: 6, ), Text( readPromise['verse'], style: const TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.bold), ), const SizedBox( width: 140, ), Text( readPromise['date'], style: const TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.bold), ), ], ) ] ) ))); } }
内容的提问来源于stack exchange,提问作者ashish rana
相关产品推荐
相关产品推荐

