【发布时间】:2020-06-01 20:14:28
【问题描述】:
上下文:这是我在 Android 中的第一个项目,我在问一些愚蠢的问题,但我找不到任何方向(当然,我把以前关于 Angular/Srping 的知识与 Android/Kotlin 搞混了)
目标:Android 应用会从某个后端微服务获取一个 Firestore 自定义令牌,然后开始监听一个文档。到现在为止还挺好。我阅读了关于如何关闭/分离监听的良好实践,我相信我已经通过将 Android 活动作为第一个参数传递给快照成功地做到了这一点。到目前为止也很好。但就我而言,我必须在 10 分钟后或收到文档中的特定值后关闭/分离快照监听。现在我真的卡住了。
我尝试了想象中最简单的第一步,并且从这个主题中得到了天真的警告。所以我的直截了当的问题是:为什么它总是抱怨为 ALWAYS TRUE 条件?来自 Android 专家的补充评论是如何在 10 分钟后关闭/分离快照,以及我是否从收听的文档中收到特定值。请接受这两个条件中的任何一个都需要停止侦听并仍然保留在相同 MainActivity.kt 中的想法。
这是在 onStop 循环阶段尝试检查时带有警告的代码
package com.mycomp.appfirestore
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.EventListener
import com.google.firebase.firestore.FirebaseFirestore
import com.mycomp.appfirestore.data.service.Endpoint
import com.mycomp.appfirestore.data.service.NetworkUtils
import com.mycomp.appfirestore.model.Transfer
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainActivity : AppCompatActivity() {
lateinit var auth: FirebaseAuth
lateinit var listenerReg : FirebaseFirestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btnTransfer = findViewById(R.id.btnTransfer) as Button
val textViewTransfer = findViewById(R.id.textViewTransfer) as TextView
btnTransfer.setOnClickListener {
getToken()
}
}
fun getToken() {
val retrofitClient = NetworkUtils
.getRetrofitInstance("http://192.168.15.13:8080/")
val endpoint = retrofitClient.create(Endpoint::class.java)
...
callback.enqueue(object : Callback<Transfer> {
override fun onFailure(call: Call<Transfer>, t: Throwable) {
Toast.makeText(baseContext, t.message, Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<Transfer>, response: Response<Transfer>) {
listenStatus()
}
})
}
fun listenStatus() {
val TAG = "ListenStatus"
auth = FirebaseAuth.getInstance()
// to make simple for this question let's say the backend returned a valid customtoken used here
auth.signInWithCustomToken("eyJ **** gXsQ")
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Log.d(TAG, "*** signInWithCustomToken:success")
startSnapshot()
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCustomToken:failure", task.exception)
Toast.makeText(
baseContext, "Authentication failed.",
Toast.LENGTH_SHORT
).show()
}
}
}
fun startSnapshot() {
val TAG = "StartSnapshot"
//Try to pass this(activity context) as first parameter.It will automatically handle acivity life cycle.
// Example if you are calling this listener in onCreate() and passing this as a first parameter then
// it will remove this listener in onDestroy() method of activity.
listenerReg = FirebaseFirestore.getInstance()
listenerReg.collection("transfer")
.document("sDme6IRIi4ezfeyfrU7y")
.addSnapshotListener(
this,
EventListener<DocumentSnapshot?> { snapshot, e ->
if (e != null) {
Log.w(TAG, "Listen failed.", e)
return@EventListener
}
if (snapshot != null && snapshot.exists()) {
textViewTransfer.text = snapshot.data!!["status"].toString()
//Log.d(TAG, snapshot.data!!["status"].toString())
} else {
Log.d(TAG, "Current data: null")
}
})
}
//here I get the warnning mentioned in my question topic
fun stopSnapshot() {
if (listenerReg != null) {
listenerReg.remove()
}
}
}
我知道,由于我将活动添加为快照的第一个参数,因此活动很快就会离开,它会自动分离监听。但是我还有两个条件可以停止听:
1 - 10 分钟后
2 - 如果我得到一个特定的返回值
所以作为想象中的解决方案,我会或多或少地尝试
...
EventListener<DocumentSnapshot?> { snapshot, e ->
if (e != null) {
Log.w(TAG, "Listen failed.", e)
return@EventListener
}
if (snapshot != null && snapshot.exists()) {
textViewTransfer.text = snapshot.data!!["status"].toString()
**** imagined solution ****
if (snapshot.data!!["status"].toString() == "FINISH"){
stopSnapshot()
}
//Log.d(TAG, snapshot.data!!["status"].toString())
} else {
Log.d(TAG, "Current data: null")
}
})
...
**** imagined solution ***
listenerReg.timeout(10000, stopSnapshot())
【问题讨论】:
标签: android firebase kotlin google-cloud-firestore