Android端如何将Firebase返回的Timestamp类型转换为String
报错原因
反序列化失败的核心原因是:Firestore 中datahorario字段存储的是com.google.firebase.Timestamp类型,但你的Posts类里把该字段声明为String类型,Firestore SDK 无法自动完成跨类型转换,直接抛出异常。
解决方法
第一步:修改Posts实体类的字段类型
将datahorario的类型从String改为Firestore对应的Timestamp类型,同步修改构造方法、getter、setter的对应参数类型即可,其他字段逻辑保持不变。
// 新增导入 import com.google.firebase.Timestamp; import java.text.SimpleDateFormat; import java.util.Locale; public class Posts { // 其余字段保持原有定义不变,仅修改datahorario的类型 String descricao, titulo, categoria, fotourl, latitude, longitude, anonimo, pais, estado, cidade, endereco, usuario; Timestamp datahorario; public Posts(){} // 构造方法中datahorario参数类型改为Timestamp public Posts(Timestamp datahorario, String descricao, String titulo, String categoria, String fotourl, String latitude, String longitude, String anonimo, String pais, String estado, String cidade, String endereco, String usuario) { this.titulo = titulo; this.descricao = descricao; this.categoria = categoria; this.fotourl = fotourl; this.latitude = latitude; this.longitude = longitude; this.anonimo = anonimo; this.datahorario = datahorario; this.pais = pais; this.estado = estado; this.cidade = cidade; this.endereco = endereco; this.usuario = usuario; } // 修改datahorario对应的getter、setter类型 public Timestamp getDatahorario() {return datahorario; } public void setDatahorario(Timestamp datahorario) { this.datahorario = datahorario; } // 其余字段的getter、setter完全保留原有代码即可 }
注:你之前写入数据时使用Date类型的写法是兼容的,Firestore SDK会自动将Date转换为Timestamp格式存储,读取时也能直接映射为Timestamp类型。
第二步:格式化Timestamp为字符串后设置到TextView
从Firestore拿到Posts实例后,不要直接将datahorario字段设置给TextView,先将Timestamp转换为Date,再通过时间格式化工具转为需要的字符串格式:
// 从快照映射得到Posts对象 Posts post = documentSnapshot.toObject(Posts.class); // 自定义时间显示格式,可按需调整,比如"yyyy年MM月dd日 HH:mm" SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()); // Timestamp转Date后格式化为字符串 String showTime = sdf.format(post.getDatahorario().toDate()); // 将格式化后的字符串设置给对应TextView timeTextView.setText(showTime);
如果需要适配系统本地化的时间显示规则,可以直接使用系统提供的DateFormat类,无需自定义格式:
DateFormat localFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault()); String localTimeStr = localFormat.format(post.getDatahorario().toDate());
可选方案(不推荐):不修改实体类手动转换
如果你不想修改实体类中datahorario的String类型定义,就不能直接调用toObject(Posts.class)做自动映射,需要手动从文档快照中取值、转换后再赋值给实体类:
DocumentSnapshot snapshot = task.getResult(); Posts post = new Posts(); // 手动给其余字段赋值... // 单独处理时间字段 Timestamp ts = snapshot.getTimestamp("datahorario"); if (ts != null) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()); post.setDatahorario(sdf.format(ts.toDate())); }
这种方案需要手动维护所有字段的映射逻辑,后续新增字段容易遗漏,优先选择第一种修改实体类类型的方案。
内容的提问来源于stack exchange,提问作者Marcelo Pontes Machado
相关产品推荐
相关产品推荐

