如何通过Firebase Storage/Firestore判断资源是图片还是视频
解决Firestore中判断Storage资源是图片还是视频的问题
最优方案:上传时同步存储资源类型
你当前的代码只存储了资源的下载URL,没有记录类型信息。最直接高效的方式是在上传阶段就获取每个文件的MIME类型,和URL一起存入Firestore,这样后续查询时无需额外请求就能直接判断类型。
修改上传代码
在获取下载URL的同时,从上传任务的元数据中提取contentType(即MIME类型,比如image/jpeg、video/mp4),将URL和类型封装成对象后再存入列表:
Tasks.whenAllSuccess<UploadTask>(tasks).addOnSuccessListener { val resources = mutableListOf<Map<String, String>>() var count = 0 for (i in 0 until tasks.size) { val metadata = tasks[i].result.metadata!! metadata.reference!!.downloadUrl.addOnSuccessListener { uri -> val contentType = metadata.contentType ?: "" // 封装URL和类型到Map中 val resource = mapOf( "url" to uri.toString(), "type" to contentType ) resources.add(resource) count++ if (count == tasks.size) { progressDialog.dismiss() saveInDatabase(resources) } } } } private fun saveInDatabase(resources: MutableList<Map<String, String>>) { val time = System.currentTimeMillis().toString() val userHashMap = HashMap<String, Any>() if (resources.isNotEmpty()) { userHashMap["timestamp"] = time userHashMap["type"] = mainType userHashMap["img"] = mainImage userHashMap["preis"] = 845 // 存储包含URL和类型的资源列表 userHashMap["listResources"] = resources } // 其余代码保持不变 if (latt != 0.0 && longt != 0.0) { userHashMap["long"] = longt userHashMap["lat"] = latt } if (objektBeschreibung.text.toString().isNotEmpty()) { userHashMap["beschreibung"] = objektBeschreibung.text.toString() } if (objektName.text.toString().isNotEmpty()) { userHashMap["name"] = objektName.text.toString() } db.collection("USER").document(auth.currentUser!!.uid) .collection("Objekte").document(time) .set(userHashMap, SetOptions.merge()) .addOnSuccessListener { Toast.makeText(ctx, "Erfolgreich angelegt", Toast.LENGTH_LONG).show() } }
后续判断类型
当你从Firestore读取listResources列表后,只需检查每个对象的type字段:
- 以
image/开头的是图片(比如image/png、image/jpeg) - 以
video/开头的是视频(比如video/mp4、video/quicktime)
示例代码:
// 假设从Firestore读取到的资源列表 val resources = document.get("listResources") as List<Map<String, String>> for (resource in resources) { val url = resource["url"] val type = resource["type"] when { type?.startsWith("image/") == true -> { // 处理图片逻辑 } type?.startsWith("video/") == true -> { // 处理视频逻辑 } } }
备选方案:通过URL反向获取Storage元数据
如果已经有历史数据无法修改,可以通过下载URL解析出Storage引用,再获取元数据判断类型。但这种方式需要额外的网络请求,效率较低,不推荐频繁使用:
val storage = FirebaseStorage.getInstance() val resourceUrl = "你的资源URL" val storageRef = storage.getReferenceFromUrl(resourceUrl) storageRef.metadata.addOnSuccessListener { metadata -> val contentType = metadata.contentType when { contentType?.startsWith("image/") == true -> { // 是图片 } contentType?.startsWith("video/") == true -> { // 是视频 } } }.addOnFailureListener { // 处理元数据获取失败的情况 }
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

