来自 Firebase Firestore 的 Android 反应式列表
Posted
技术标签:
【中文标题】来自 Firebase Firestore 的 Android 反应式列表【英文标题】:Reactive list on Android from Firebase Firestore 【发布时间】:2021-12-30 02:26:48 【问题描述】:我试图在从 Firestore 下载一些数据后更新 RecyclerView,但当数据更改时它似乎不会更新 UI。以下是主要活动:
class MainActivity : AppCompatActivity()
private lateinit var dbService: DatabaseManager
private var mBound: Boolean = false
private val restaurantListModel: RestaurantList by viewModels()
val data = ArrayList<RestaurantCardModel>()
val adapter = RestaurantListAdapter(data)
/** Defines callbacks for service binding, passed to bindService() */
private val connection = object : ServiceConnection
override fun onServiceConnected(className: ComponentName, service: IBinder)
// We've bound to LocalService, cast the IBinder and get LocalService instance
val binder = service as DatabaseManager.LocalBinder
dbService = binder.getService()
mBound = true
dbService.read_restaurants(object: MyCallback
override fun onCallback(value: MutableList<Restaurant>)
restaurantListModel.restList.value = value
updateView()
)
override fun onServiceDisconnected(arg0: ComponentName)
mBound = false
fun updateView()
for (rest in restaurantListModel.restList.value!!)
data.add(RestaurantCardModel(R.drawable.pizza_express_logo, rest.name, 5, rest.review, rest.no_review,
R.color.colorPrimary))
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Bind to LocalService
Intent(this, DatabaseManager::class.java).also intent ->
bindService(intent, connection, Context.BIND_AUTO_CREATE)
// getting the recyclerview by its id
val recyclerview = findViewById<RecyclerView>(R.id.restaurant_recyclerview)
// this creates a vertical layout Manager
recyclerview.layoutManager = LinearLayoutManager(this)
// Setting the Adapter with the recyclerview
recyclerview.adapter = adapter
if(mBound) updateView()
override fun onResume()
super.onResume()
if (mBound) updateView()
override fun onStart()
super.onStart()
override fun onStop()
super.onStop()
unbindService(connection)
mBound = false
然后你有我的数据库管理器从 firebase 获取数据:
class DatabaseManager : Service()
// Binder given to clients
private val binder = LocalBinder()
var db = FirebaseFirestore.getInstance()
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
return super.onStartCommand(intent, flags, startId)
fun upload_review(review_data: String)
fun read_restaurants(myCallback : MyCallback): MutableList<Restaurant>
var restList : MutableList<Restaurant> = mutableListOf()
db.collection("restaurant")
.get()
.addOnCompleteListener task ->
if (task.isSuccessful)
restList = updateRestaurantList(task.result!!)
myCallback.onCallback(restList)
else
Log.w(TAG, "Error getting documents.", task.exception)
return restList
private fun updateRestaurantList(restaurants: QuerySnapshot): MutableList<Restaurant>
var restList : MutableList<Restaurant> = mutableListOf()
for (doc in restaurants.documents)
Log.d(TAG, doc.toString())
var tempRest : Restaurant? = doc.toObject(Restaurant::class.java)?.withId(doc.id)
if (tempRest != null)
restList.add(tempRest)
return restList
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
inner class LocalBinder : Binder()
// Return this instance of LocalService so clients can call public methods
fun getService(): DatabaseManager = this@DatabaseManager
override fun onBind(intent: Intent): IBinder
return binder
当我在 onCreate() 方法中手动添加数据时,回收器视图工作正常,但一旦 firebase 完成后不会更新视图,我们将不胜感激。
【问题讨论】:
【参考方案1】:当我在 onCreate() 方法中手动添加数据但不更新视图时,回收器视图工作正常
这是预期的行为,因为您使用的是 .get()
调用,这基本上意味着您只获取一次数据。您正在寻找的是listening for real-time updates。所以你必须使用addSnapshotListener()
调用。
除此之外,还有一个名为FirebaseUI for android 的有用库,它对Cloud Firestore 有特定用途。
【讨论】:
以上是关于来自 Firebase Firestore 的 Android 反应式列表的主要内容,如果未能解决你的问题,请参考以下文章
使用来自 firebase 实时数据库的 json 数据填充 firestore 数据库
如何将来自不同组件的 firebase auth 和 Cloud Firestore 用作单个 Firebase 应用程序
在 Angular 11 网站上使用 Firestore 和 Firebase 存储进行图像上传功能导致来自 Firebase 的不安全规则通知
Flutter:显示来自经过身份验证的 Firebase Auth 用户的带有 StreamBuilder 的一些 Firestore 集合