Flutter中Firestore数据排序异常求助:日期与浏览量排序失效
解决Firestore中日期和浏览量的排序问题
我来帮你搞定这两个排序的问题,这俩坑我之前开发类似问答App的时候也踩过,核心问题都是字段类型不匹配导致Firestore的排序逻辑不符合预期:
一、日期排序失效的问题
你现在把日期存在字符串类型(比如"29 September 2019"),Firestore对字符串的排序是按字典序来的,这和实际的时间顺序完全不一致。举个例子:"01 October 2019"的字典序会比"29 September 2019"小,所以你用descending: true倒序的时候,反而会把九月的日期排在十月前面,这显然不是你要的最新日期排序。
解决方案:
把日期字段改成Firestore原生的Timestamp类型或者长整型时间戳:
- 存储时修改字段类型:
- 用Timestamp:存数据的时候直接用
FieldValue.serverTimestamp()或者Timestamp.fromDate(DateTime.now()),这样Firestore会自动存储为Timestamp类型。 - 用长整型:存
DateTime.now().millisecondsSinceEpoch(当前时间的毫秒数,数字类型)。
- 用Timestamp:存数据的时候直接用
- 查询时保持排序代码:
不管用哪种类型,你的查询代码Firestore.instance.collection("Questions").orderBy("date", descending: true).snapshots()都会生效,因为Firestore会按时间先后(Timestamp)或者数值大小(长整型)来排序。
二、浏览量排序失效的问题
和日期的问题类似,你把questionsView存在字符串类型(比如"3"、"1032"),Firestore对字符串数字的排序还是按字典序来的。比如"1032"的字典序比"3"小,所以你不加descending: true的话,会把"1032"排在"3"前面,但实际数值1032比3大;如果加了倒序,又会把"3"排在"1032"前面,完全不符合“最高浏览量”的需求。
解决方案:
把questionsView改成整数类型:
- 存储时修改字段类型:
存浏览量的时候直接存整数,比如3而不是"3",更新浏览量的时候也要用数字递增(比如FieldValue.increment(1)),不要拼接字符串。 - 查询时调整代码:
如果要按最高浏览量排序,需要加上descending: true,代码应该是:Firestore.instance.collection("Questions").orderBy("questionsView", descending: true).snapshots()
补充说明
你提到的Frank的《Ordering Data In FireStore》核心逻辑就是:Firestore的排序完全依赖字段的原生数据类型——字符串按字符顺序、数字按数值大小、日期/时间戳按时间先后。只要字段类型和你想要的排序逻辑匹配,排序就会正常生效。
内容的提问来源于stack exchange,提问作者Rusben Wladiskoz
相关产品推荐
相关产品推荐

