【问题标题】:Firestore addSnapshotListener doesn't workFirestore addSnapshotListener 不起作用
【发布时间】: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 是的,有。上一个版本显示数据很好..

标签: android firebase kotlin google-cloud-firestore


【解决方案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

【讨论】:

  • 上帝.. 非常感谢.. 我觉得很傻。正如你所说,我已经改变了初始化策略。我应该对此更加小心。再次感谢!
猜你喜欢
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多