Firestore addSnapshotListener 不起作用

Posted

技术标签:

【中文标题】Firestore addSnapshotListener 不起作用【英文标题】:Firestore addSnapshotListener doesn't work 【发布时间】:2021-01-14 17:27:12 【问题描述】:

从字面上看,它不起作用。 没有错误,但没有开始与服务器联网。

奇怪的是这个应用程序的早期版本运行良好。这段代码和以前的版本没有区别..

我认为代码还不错,但是还有一个我想不通的问题...

class FeedFragment : Fragment() 
    var firestore : FirebaseFirestore? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 

        var feedView: View = inflater.inflate(R.layout.fragment_feed, container, false)
        feedView.feed_recycler_view?.adapter = FeedRecyclerViewAdapter()
        feedView.feed_recycler_view?.layoutManager = GridLayoutManager(activity, 2)

        firestore = FirebaseFirestore.getInstance()
        if (firestore == null) Log.d("firestore", "doesnt work")
        else 
            Log.d("print", firestore.toString())
            // it throws the instance properly
        
        return feedView
    

    inner class FeedRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() 
        var contentDTOs: ArrayList<ContentDTO> = arrayListOf()

        init 
            firestore?.collection("images")?.addSnapshotListener 
                    querySnapshot, _ ->
                
                // Log.d("query", "working")
                // I can't see this log because the query doesn't work

                //Sometimes, this code return null of querySnapshot when it signout
                if (querySnapshot == null) return@addSnapshotListener

                // Get data
                for (snapshot in querySnapshot.documents) 
                    contentDTOs.add(snapshot.toObject(ContentDTO::class.java)!!)
                
                notifyDataSetChanged()
            
        

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
            // 화면 넓이의 1/2 크기의 정사각형 만들기
            var width = resources.displayMetrics.widthPixels / 2
            var imageView = ImageView(parent.context)
            imageView.layoutParams = LinearLayoutCompat.LayoutParams(width, width)
            return CustomViewHolder(imageView)
        

        inner class CustomViewHolder(var imageview: ImageView) : RecyclerView.ViewHolder(imageview)

        override fun getItemCount(): Int 
            return contentDTOs.size
        

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
            var imageview = (holder as CustomViewHolder).imageview
            Glide.with(holder.itemView.context).load(contentDTOs[position].imageUri)
                .apply(RequestOptions().centerCrop()).into(imageview)
        

    

【问题讨论】:

图片集合中有数据吗? @MuhammadUmar 是的,有。上一个版本显示数据很好.. 【参考方案1】:

在 FeedRecyclerViewAdapter 的构造函数中,您引用了外部类的 firestore 属性。在初始化firestore 属性的值之前,在onCreateView 中创建此适配器的一个实例(反过来调用其构造函数)。由于Adapters 构造函数中的安全调用,您看不到任何错误,但从未调用过addSnapshotListener

在 kotlin 中,一般应该避免这种奇怪的初始化策略。为什么firestore 可以为空? firestore = null 是此类的有效状态吗? firestore 实例会改变吗?如果你不想显式地从 Fragment 实例中“分离”这个对象(我不明白在这种情况下你为什么要这样做),你应该使用更惯用的方法来初始化一个属性:

构造过程中初始化:private val firestore = ... 延迟初始化 - 当初始化应该推迟到第一次使用属性时:private val firestore by lazy ... lateinit 属性 - 当您想手动初始化值但在初始化之前使用它时无效:private lateinit var firestore: Firestore

【讨论】:

上帝.. 非常感谢.. 我觉得很傻。正如你所说,我已经改变了初始化策略。我应该对此更加小心。再次感谢!

以上是关于Firestore addSnapshotListener 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Firestore:加入与 Firestore 定价

React Native重复超时将集合写入firestore@firebase/firestore:Firestore(8.4.2):连接WebChannel传输错误

@firebase/firestore:Firestore (5.0.4):无法访问 Cloud Firestore 后端。后端在 10 秒内没有响应

Expo + firebase@9.0.1/9.0.0: @firebase/firestore:, Firestore (9.0.0): 无法到达 Cloud Firestore 后端

类型错误:firestore.collection 不是函数(React、Redux、Firestore)

Swiftui + Firestore - 无法访问 Firestore 中的字段