Firebase实时数据库子路径未被识别,监听器仅生效于根节点
问题描述
我为Firebase数据库引用添加子节点后,尝试给包含uid的usersRef添加监听器,发现监听器仅对users根节点生效,并未监听指定的uid子节点。打印路径时也只显示根节点地址:
path- https://.....-default-rtdb.firebaseio.com/users
该问题在iOS和Android端均出现。目前只有强制解包uid的写法能正常工作,但我不想使用强制解包。
原代码
iOS(Swift)
var usersRef = Database.database().reference().child("users") override func viewDidLoad() { super.viewDidLoad() guard let uid = Auth.auth().currentUser?.uid else { return } usersRef.child(uid) let path = usersRef.description() print("path- \(path)") query = usersRef.queryOrderedByKey() listenerRefHandle = query?.observe(.childAdded) { (snapshot) in } }
Android(Kotlin)
var usersRef = Firebase.database.reference.child("users") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) FirebaseAuth.getInstance().uid?.let { uid -> usersRef.child(uid) val path = usersRef.toString().substring(usersRef.root.toString().length-1) println("path- $path") query = usersRef listenerRefHandle = query?.addChildEventListener(object : ChildEventListener { }) } }
问题原因
Firebase的Database引用是不可变对象,调用child(uid)方法不会修改原有的usersRef引用,而是返回一个指向目标子节点的新引用。你只是调用了usersRef.child(uid)但没有将返回值重新赋值给usersRef,所以原引用依然指向users根节点,监听器自然只会监听根节点的变化。
修正方案
不需要强制解包uid,只需将child(uid)返回的新引用赋值给usersRef即可:
iOS(Swift)修正后
var usersRef = Database.database().reference().child("users") override func viewDidLoad() { super.viewDidLoad() guard let uid = Auth.auth().currentUser?.uid else { return } // 将新引用赋值给usersRef usersRef = usersRef.child(uid) let path = usersRef.description() print("path- \(path)") query = usersRef.queryOrderedByKey() listenerRefHandle = query?.observe(.childAdded) { (snapshot) in // 处理子节点数据 } }
Android(Kotlin)修正后
var usersRef = Firebase.database.reference.child("users") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) FirebaseAuth.getInstance().uid?.let { uid -> // 将新引用赋值给usersRef usersRef = usersRef.child(uid) val path = usersRef.toString().substring(usersRef.root.toString().length-1) println("path- $path") query = usersRef listenerRefHandle = query?.addChildEventListener(object : ChildEventListener { // 实现回调方法 }) } }
这样既避免了强制解包,又能让监听器正确指向uid对应的子节点。
内容的提问来源于stack exchange,提问作者Lance Samaria
相关产品推荐
相关产品推荐

