Firebase图片字段映射失败,Glide无法加载图片问题求助
问题解决:Firebase ClassMapper警告+Glide图片加载失败
问题现象
尝试用Glide加载Firebase Storage中的图片URL时,LogCat出现ClassMapper警告,提示Post类的post_image、User类的background_image和profile_image字段找不到对应的setter或字段,其他Firebase数据可正常获取,仅图片无法加载。
日志信息
2023-02-14 10:02:36.417 25063-25063/com.isjieman.ocion W/ClassMapper: No setter/field for post_image found on class com.isjieman.ocion.model.Post 2023-02-14 10:02:36.436 25063-25063/com.isjieman.ocion W/ClassMapper: No setter/field for background_image found on class com.isjieman.ocion.model.User 2023-02-14 10:02:36.436 25063-25063/com.isjieman.ocion W/ClassMapper: No setter/field for profile_image found on class com.isjieman.ocion.model.User 2023-02-14 10:02:36.438 25063-25063/com.isjieman.ocion W/Glide: Load failed for with size [960x240] class com.bumptech.glide.load.engine.GlideException: Failed to load resource
数据库结构
{ "Posts": { "-NNsor5WiX9wxTDf7qo5": { "category": "Art", "description": "tes 123", "duration": "-", "paymentMethods": "e-wallet", "postId": "-NNsor5WiX9wxTDf7qo5", "post_image": "https://firebasestorage.googleapis.com/v0/b/final-project-idn.appspot.com/o/Posts%20Pictures%2F1675990621049.jpg?alt=media&token=f7b747c0-1efe-4f43-9ff1-729c7d99c7c1", "priceRange": "Rp 0 - 10.000", "publisher": "6FzpJ2sQC9gewbUIGHB8hiNWK1z2", "title": "tes" } }, "User": { "6FzpJ2sQC9gewbUIGHB8hiNWK1z2": { "background_image": "https://firebasestorage.googleapis.com/v0/b/final-project-idn.appspot.com/o/Default%20Images%2Fimg_background.png?alt=media&token=b51e7cf5-2015-4cc4-9583-159373d081e2", "bio": "Member of NCT", "email": "mark@gmail.com", "link": "", "profile_image": "https://firebasestorage.googleapis.com/v0/b/final-project-idn.appspot.com/o/Profile%20Pictures%2F6FzpJ2sQC9gewbUIGHB8hiNWK1z2.jpg?alt=media&token=d174fad9-2f8c-4964-83ec-549f18876587", "uid": "6FzpJ2sQC9gewbUIGHB8hiNWK1z2", "userName": "marklee" } } }
问题原因
Firebase Realtime Database的ClassMapper遵循JavaBean命名规范进行字段映射:
- 数据库中下划线分隔的字段名(如
post_image),默认会被转换为驼峰式命名(postImage)去匹配模型类的字段或setter方法。 - 当前模型类中,字段名使用下划线(如
post_image),但setter/getter使用驼峰命名(setPostImage/getPostImage),导致ClassMapper无法找到对应映射,字段值无法被正确赋值,最终Glide加载空字符串导致失败。
解决方案
有两种可行的修复方式,任选其一即可:
方式一:修改模型类字段名为驼峰式
将模型类中的下划线字段名改为驼峰命名,与setter/getter保持一致,Firebase会自动完成下划线到驼峰的映射:
修改后的User类示例
class User { private var uid: String = "0" private var userName: String = "" private var email: String = "" private var bio: String? = null private var link: String? = null private var profileImage: String = "" private var backgroundImage: String = "" constructor() constructor(uid : String, userName : String, email : String, bio : String, link : String, profileImage : String, backgroundImage : String){ this.uid = uid this.userName = userName this.email = email this.bio = bio this.link = link this.profileImage = profileImage this.backgroundImage = backgroundImage } // UID相关方法 fun getUID(): String{ return uid } fun setUID(uid: String){ this.uid = uid } // UserName相关方法 fun getUserName(): String{ return userName } fun setUserName(userName: String){ this.userName = userName } // Email相关方法 fun getEmail(): String{ return email } fun setEmail(email: String){ this.email = email } // Bio相关方法 fun getBio(): String?{ return bio } fun setBio(bio: String?){ this.bio = bio } // Link相关方法 fun getLink(): String?{ return link } fun setLink(link: String?){ this.link = link } // ProfileImage相关方法 fun getProfileImage(): String{ return profileImage } fun setProfileImage(profileImage: String){ this.profileImage = profileImage } // BackgroundImage相关方法 fun getBackgroundImage(): String{ return backgroundImage } fun setBackgroundImage(backgroundImage: String){ this.backgroundImage = backgroundImage } }
修改后的Post类示例
class Post { private var postId: String = "" private var title: String = "" private var postImage: String = "" private var description: String = "" private var category: String = "" private var priceRange: String = "" private var duration: String = "" private var paymentMethods: String = "" private var publisher: String = "" constructor() constructor( postId: String, title: String, postImage: String, description: String, category: String, priceRange: String, duration: String, paymentMethods: String, publisher: String ) { this.postId = postId this.title = title this.postImage = postImage this.description = description this.category = category this.priceRange = priceRange this.duration = duration this.paymentMethods = paymentMethods this.publisher = publisher } // Get方法 fun getPostId(): String{ return postId } fun getTitle(): String{ return title } fun getPostImage(): String{ return postImage } fun getDescription(): String{ return description } fun getCategory(): String{ return category } fun getPriceRange(): String{ return priceRange } fun getDuration(): String{ return duration } fun getPaymentMethods(): String{ return paymentMethods } fun getPublisher(): String{ return publisher } // Set方法 fun setPostId(postId: String){ this.postId = postId } fun setTitle(title: String){ this.title = title } fun setPostImage(postImage: String){ this.postImage = postImage } fun setDescription(description: String){ this.description = description } fun setCategory(category: String){ this.category = category } fun setPriceRange(priceRange: String){ this.priceRange = priceRange } fun setDuration(duration: String){ this.duration = duration } fun setPaymentMethods(paymentMethods: String){ this.paymentMethods = paymentMethods } fun setPublisher(publisher: String){ this.publisher = publisher } }
方式二:使用@PropertyName注解指定字段名
如果不想修改字段名,可以给模型类的下划线字段添加@PropertyName注解,明确指定数据库中的字段名:
注解后的User类示例
import com.google.firebase.database.PropertyName class User { private var uid: String = "0" private var userName: String = "" private var email: String = "" private var bio: String? = null private var link: String? = null @PropertyName("profile_image") private var profile_image: String = "" @PropertyName("background_image") private var background_image: String = "" constructor() constructor(uid : String, userName : String, email : String, bio : String, link : String, profile_image : String, background_image : String){ this.uid = uid this.userName = userName this.email = email this.bio = bio this.link = link this.profile_image = profile_image this.background_image = background_image } // UID相关方法 fun getUID(): String{ return uid } fun setUID(uid: String){ this.uid = uid } // UserName相关方法 fun getUserName(): String{ return userName } fun setUserName(userName: String){ this.userName = userName } // Email相关方法 fun getEmail(): String{ return email } fun setEmail(email: String){ this.email = email } // Bio相关方法 fun getBio(): String?{ return bio } fun setBio(bio: String?){ this.bio = bio } // Link相关方法 fun getLink(): String?{ return link } fun setLink(link: String?){ this.link = link } // ProfileImage相关方法 @PropertyName("profile_image") fun getProfileImage(): String{ return profile_image } @PropertyName("profile_image") fun setProfileImage(profile_image: String){ this.profile_image = profile_image } // BackgroundImage相关方法 @PropertyName("background_image") fun getBackgroundImage(): String{ return background_image } @PropertyName("background_image") fun setBackgroundImage(background_image: String){ this.background_image = background_image } }
注解后的Post类示例
import com.google.firebase.database.PropertyName class Post { private var postId: String = "" private var title: String = "" @PropertyName("post_image") private var post_image: String = "" private var description: String = "" private var category: String = "" private var priceRange: String = "" private var duration: String = "" private var paymentMethods: String = "" private var publisher: String = "" constructor() constructor( postId: String, title: String, post_image: String, description: String, category: String, priceRange: String, duration: String, paymentMethods: String, publisher: String ) { this.postId = postId this.title = title this.post_image = post_image this.description = description this.category = category this.priceRange = priceRange this.duration = duration this.paymentMethods = paymentMethods this.publisher = publisher } // Get方法 fun getPostId(): String{ return postId } fun getTitle(): String{ return title } @PropertyName("post_image") fun getPostImage(): String{ return post_image } fun getDescription(): String{ return description } fun getCategory(): String{ return category } fun getPriceRange(): String{ return priceRange } fun getDuration(): String{ return duration } fun getPaymentMethods(): String{ return paymentMethods } fun getPublisher(): String{ return publisher } // Set方法 fun setPostId(postId: String){ this.postId = postId } fun setTitle(title: String){ this.title = title } @PropertyName("post_image") fun setPostImage(post_image: String){ this.post_image = post_image } fun setDescription(description: String){ this.description = description } fun setCategory(category: String){ this.category = category } fun setPriceRange(priceRange: String){ this.priceRange = priceRange } fun setDuration(duration: String){ this.duration = duration } fun setPaymentMethods(paymentMethods: String){ this.paymentMethods = paymentMethods } fun setPublisher(publisher: String){ this.publisher = publisher } }
验证修复
修改完成后,重新运行项目,ClassMapper警告会消失,Firebase能正确赋值图片URL,Glide即可正常加载图片。
内容的提问来源于stack exchange,提问作者dsneykhsa
相关产品推荐
相关产品推荐

