FIRESTORE持久数据

时间:2017-11-22 12:19:57

标签: android firebase kotlin google-cloud-firestore persistent

谈论firestore持久性数据,假设用户在第一次启动应用程序时没有任何连接。我向Firestore数据库添加了一些数据(比如userID ..),我可以用get()方法取回它。现在用户关闭了应用程序。

  1. 下次他将打开应用程序(仍然没有连接),他是否能够检索先前存储的数据,就像它以sharedprefs的方式存储一样? 我无法清楚地弄清楚如何找到一种使用持久数据设置初始阶段的正确方法。

  2. 我有几个片段。每次启动其中一个,我都会使用" onResume"从数据填充我的组件的方法(以前存储在sharedpref中)。当我设置Firestore getData时,需要时间来检索。因此,如果用户从当前片段更改为另一个片段,则当连接打开时,我在组件完成时,组件为空或无法访问时出错。

    实施此类" onResume"的最佳方式是什么?数据补充?

  3. 更新:

    以下是一段代码: 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 类中的

    :第一次启动时发生 - >

    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<String,Any?>()
            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<DocumentSnapshot> {
                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<MenuData>()
            var vars: MutableMap<String,Any>? =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,它无需在线和离线延迟工作。

    **必须有一种更好的方法来从snapshot.getData()内捕获onEvent(snapshot:DocumentSnapshot?)结果,因为我希望直接从{设置我的片段args FragmentSitu.newInstance(situ,env,grd) {1}},snapshot.getData()["situ"] ...

2 个答案:

答案 0 :(得分:2)

firebaser here

Firestore会将您在设备上写入的数据保存到本地数据库。因此,下次启动应用程序时,即使设备从未连接到Firebase服务器,它也能够读取相同的数据。

当您的应用首次尝试从Firestore读取数据时,它会尝试与其服务器建立连接。如果您using get() calls to read the data,Firestore会在返回数据之前等待建立连接或失败。这意味着这个初始调用可能需要相当长的时间。我们知道这可能会导致您的应用用户出现意外行为,因此我们正在寻找改善此行为的方法。

与此同时,请考虑using realtime listeners来读取相同的数据。在这种情况下,这些监听器的行为会有所不同,并且/可能会提供两次结果:

  1. 第一个快照是直接提供的,来自本地缓存。
  2. 在客户端从云数据库获得响应后,稍后会给出第二个快照。

答案 1 :(得分:0)

正如offical documentation所说,

  

Cloud Firestore支持脱机数据持久性。此功能会缓存您的应用正在使用的Cloud Firestore数据的副本,以便您的应用可以在设备离线时访问数据。

但是为了使用此功能,您至少需要一个与dabase的连接。这意味着您的应用必须至少连接到互联网一次。之后,您将能够编写,阅读,收听和查询缓存数据。

如果您想在活动或片段之间使用数据,我会使用IntentSharedPreferences重新命令您,这可以在整个应用中保存您的数据。