从Firebase获取用户位置添加地图标记时崩溃如何解决
问题原因
崩溃日志明确抛出ClassCastException: java.lang.String cannot be cast to java.lang.Double,核心问题是你写入Firestore的经纬度字段是字符串类型,读取时直接强制转换为Double类型触发崩溃:
- 写入位置时你调用了
lt.toString()、lg.toString(),把原本是Double类型的经纬度转成了字符串存入数据库 - 读取时直接用
as Double强转,遇到字符串类型的字段值直接触发类型转换崩溃 - 你测试固定坐标
LatLng(0.0,0.0)能正常运行、注释掉经纬度强转逻辑后能正常打印online/email字段,是因为这两种场景都没有触发字符串转Double的错误逻辑。
修复方案
1. 修正写入逻辑,直接存储数值类型经纬度
不要把经纬度转成字符串再写入,直接传Double类型值:
if(document.data.getValue("email") == userEmail){ db.collection("users").document(document.id).update( mapOf( "latitude" to lt, // 去掉toString(),lt本身就是Double类型 "longitude" to lg // 去掉toString() ) ) }
2. 读取时增加类型兼容,避免旧数据崩溃
针对已经存成字符串的历史数据,做兼容转换,同时用Kotlin安全转换替代强制强转,避免类型不匹配直接崩溃:
// 替换原来直接强转构造LatLng的逻辑 val isOnline = document.data["online"] as? Boolean ?: false if(isOnline){ // 兼容String/Double两种格式的经纬度值 val lat = when(val latValue = document.data["latitude"]) { is Double -> latValue is String -> latValue.toDoubleOrNull() else -> null } val lng = when(val lngValue = document.data["longitude"]) { is Double -> lngValue is String -> lngValue.toDoubleOrNull() else -> null } // 经纬度转换有效时再添加标记 if(lat != null && lng != null){ val ocherednyara = LatLng(lat, lng) placeMarkerOnMap(ocherednyara) } }
3. 清理历史错误数据
手动修改Firestore中已存在的用户文档,把字符串格式的latitude、longitude字段改成数值类型,避免长期走兼容逻辑。
优化建议
- 目前你拉取全量用户文档再遍历匹配当前用户邮箱做更新的逻辑性能很差,可以直接用当前登录用户的UID定位文档,不需要遍历全表:
// 直接获取当前用户的文档引用,无需遍历整个users集合 val currentUserDocRef = db.collection("users").document(firebaseAuth.currentUser!!.uid) currentUserDocRef.update(mapOf( "latitude" to lt, "longitude" to lg ))
- 所有Firestore字段取值尽量用
as?安全转换搭配默认值,不要用as强制转换,避免字段类型异常、字段缺失导致的崩溃。
内容的提问来源于stack exchange,提问作者Арсен Газимов
相关产品推荐
相关产品推荐

