FIRESTORE持久性数据
谈论火灾持久性数据,让我们假设用户在第一次启动应用程序时没有任何连接。 我添加一些数据到Firestore数据库(如userID ..),我可以用get()方法取回它。 现在用户关闭应用程序。
-
下一次,他将打开应用程序(仍然没有连接),他将能够检索以前存储的数据,就像它被存储在sharedprefs的方式? 我不能清楚地弄清楚如何find一个合适的方法来建立一个永久数据的初始阶段。
-
我有几个片段。 每次启动其中一个时,我使用“onResume”方法从数据中填充我的组件(先前存储在sharedpref中)。 当我设置Firestore getData时,需要时间来检索。 因此,如果用户从当前片段更改为另一个,那么当连接为ON时,在数据库结果完成时,组件有空或无法访问的错误。
实施这种“onResume”数据再填充的最佳方式是什么?
更新:
以下是一些代码: MainAvtivity .kt
FirebaseFirestore.getInstance().firestoreSettings.isPersistenceEnabled sightingsDatabase = FirebaseFirestore.getInstance() docname=FireStoreSetup().setupFB(sightingsDatabase!!,this)
一个kotlin对象类来填充我的文档:
data class Sighting(var userID: String, var sig_wit_situation_type: Int, var sig_env_background_type: Int, var sig_ground_type: Int, var sig_YYYY: String, var sig_MM: String, var sig_DD: String, var sig_time_start: String, var sig_date_time: String, var sig_duration_hms: String, var sig_duration_milli: Int, var sig_weather_full: Int, var sig_temp: Int)
在FireStoreSetup类中:当第一个init发生时 – >
val sighting = Sighting(deviceId!!, 0, 0, 0, strDate.substring(0, 4), strDate.substring(5, 7), strDate.substring(8, 10), strDate.substring(11), strDate, "00:00:00", 0, 0, 0) db.collection("users").document(docname!!) .set(sighting) .addOnSuccessListener { Log.d(_tag, "DocumentSnapshot successfully written!") setShared(context,"doc_name",docname!!)} .addOnFailureListener { e -> Log.w(_tag, "Error writing document", e) }
然后一个有趣的写数据到服务器
fun addValue(key:String,value:Any?){ val docData = HashMap() docData.put(key, value) FirebaseFirestore.getInstance().collection("users").document(docname!!) .set(docData, SetOptions.merge()) }
和
fun readValue(){ val docRef = FirebaseFirestore.getInstance().collection("users").document(docname!!) docRef.addSnapshotListener(object:EventListener { override fun onEvent(snapshot:DocumentSnapshot?, e:FirebaseFirestoreException?) { if (e != null) { Log.w("firestore", "Listen failed.", e) } if (snapshot != null && snapshot.exists()) { Log.d("firestore", "Current data: " + snapshot.getData()) FragmentHome.vars=snapshot.getData() } else { Log.d("firestore", "Current data: null") } } }) }
在FragmentHome :
companion object { val itemsMenu = ArrayList() var vars: MutableMap? =null fun newInstance(value: Int): FragmentHome { val args = Bundle() args.putInt("menu", value) val fragment = FragmentHome() fragment.arguments = args return fragment } } override fun onResume() { super.onResume() FireStoreSetup().readValue() when (_menu){ 0-> switchRecycler(1,0) 1-> switchRecycler(0,0) } }
然后从fragmentHome中将其替换为具有firestore值的新片段:
val situ= vars!!["sig_wit_situation_type"].toString().toInt() val env= vars!!["sig_env_background_type"].toString().toInt() val grd= vars!!["sig_ground_type"].toString().toInt() reFrag(FragmentSitu.newInstance(situ,env,grd), 1)
在新的FragmentSitu片段中,我们有:
companion object { fun newInstance(situ: Int,env: Int,grd: Int): FragmentSitu { val args = Bundle() args.putInt("sig_wit_situation_type", situ) args.putInt("sig_env_background_type", env) args.putInt("sig_ground_type", grd) val fragment = FragmentSitu() fragment.arguments = args return fragment } }
而且它在线和离线都没有延迟,这要感谢Franck和docRef.addSnapshotListener。
**必须有更好的方法从onEvent(snapshot:DocumentSnapshot?)
捕获snapshot.getData()
结果,因为我希望直接从snapshot.getData()["situ"]
设置片段参数FragmentSitu.newInstance(situ,env,grd) snapshot.getData()["situ"]
, snapshot.getData()["env"]
…
firebaser在这里
Firestore将您在设备上写入的数据保存到本地数据库。 因此,下次启动应用程序时,即使设备从未连接到Firebase服务器,也能够读取相同的数据。
当您的应用程序首先尝试从Firestore读取数据时,它会尝试建立与其服务器的连接。 如果使用get()
调用来读取数据, Firestore将在返回数据之前等待该连接建立或失败。 这意味着这个初次通话可能需要相当长的一段时间。 我们知道,这可能会导致您的应用程序的用户不想要的行为,所以我们正在寻找方法来改善这种行为。
同时,考虑使用实时监听器来读取相同的数据。 这些监听器在这种情况下行为不同,并且可能会提供两次结果:
- 第一个快照是直接给出的,来自本地缓存。
- 第二个快照稍后给出,客户端已经从云数据库得到响应。
正如文件所述 ,
Cloud Firestore支持脱机数据持久性。 此function会缓存您的应用正在使用的Cloud Firestore数据的副本,因此您的应用可以在设备脱机时访问数据。
但是为了使用这个特性,至少需要一个到dabase的连接。 这意味着您的应用必须至少连接到互联网一次。 之后,您将能够编写,读取,侦听和查询缓存的数据。
如果您想在活动或片段之间使用数据,我使用Intent
或SharedPreferences
,这可以在整个应用程序中保存您的数据。