Firestore类实例操作:服务器时间获取、字段类型与格式转换问题
Firestore相关问题解答
1. 如何从类的映射中获取Firestore的服务器时间?
Firestore的服务器时间是在写入数据时通过FieldValue.serverTimestamp()作为占位符传入,Firestore会自动将其替换为服务器端的时间戳。从Firestore读取数据时,这个字段会被解析为Timestamp类型(cloud_firestore包中的类型)。要从类的映射中获取,需:
- 确保写入时的结构正确,不要将
FieldValue作为Map的键(Firestore不支持这种用法); - 读取数据后,将
Timestamp对象转换为DateTime,再按需处理成需要的格式。
2. 修正向Firestore添加数据的代码示例
你提供的代码存在问题:Firestore不支持将FieldValue作为Map的键,会导致写入失败。需要调整History类的结构,将time作为Map的字段而非键。修正后的代码如下:
FirebaseFirestore.instance.collection('collection').add({ 'history': History(FieldValue.serverTimestamp(), 'action', 'who').toMap() }).then((value) { // 处理成功逻辑 });
3. History类中time字段的正确类型及类结构修正
time字段的类型选择
- 写入Firestore时:使用
FieldValue类型,用于传入FieldValue.serverTimestamp()让Firestore生成服务器时间; - 从Firestore读取时:使用
Timestamp类型(来自cloud_firestore包),因为Firestore返回的服务器时间是Timestamp格式,后续可转换为DateTime或字符串。
修正后的History类代码
原类的history字段类型错误,且结构不符合Firestore的存储规范,修正后:
import 'package:cloud_firestore/cloud_firestore.dart'; class History { // 用dynamic兼容写入(FieldValue)和读取(Timestamp)两种场景 dynamic time; String action; String who; History(this.time, this.action, this.who); // 转换为Firestore可接受的Map格式 Map<String, dynamic> toMap() { return { 'time': time, 'action': action, 'who': who, }; } // 从Firestore读取的Map转换为History实例 factory History.fromMap(Map<String, dynamic> map) { return History( map['time'] as Timestamp, map['action'] as String, map['who'] as String, ); } }
4. 将数据转换为指定格式的字符串
首先注意你提供的目标格式存在语法错误,修正为合法的JSON结构:{"time": "October 25, 2022 at 10:44:39 PM UTC+1", "details": {"action": "action", "who": "who"}}
实现步骤:
- 依赖
intl包处理日期格式化,在pubspec.yaml中添加:
dependencies: intl: ^0.18.1
- 将
Timestamp转换为DateTime,再格式化为指定字符串:
import 'dart:convert'; import 'package:intl/intl.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; // 假设从Firestore读取到的History实例 History history = History.fromMap(snapshot.data() as Map<String, dynamic>); DateTime dateTime = (history.time as Timestamp).toDate(); // 格式化日期为指定格式,手动调整偏移显示为UTC+1 String formattedTime = DateFormat("MMMM d, yyyy 'at' hh:mm:ss a").format(dateTime) + " UTC+1"; // 构建目标Map并转换为字符串 Map<String, dynamic> targetMap = { 'time': formattedTime, 'details': { 'action': history.action, 'who': history.who, } }; String formattedString = jsonEncode(targetMap);
内容的提问来源于stack exchange,提问作者user3336191
相关产品推荐
相关产品推荐

