Firebaseなどの外部APIにアクセスするときは必ず非同期処理でかく必要があります。
以前はMVVMでその方法を説明しましたが、Viewに情報を反映しなくていい場合などの状況下ではViewModelは必要ないので、Activity/Fragmentから直接Repositoryを呼び出すことになります。ほぼMVVMとやり方は変わりませんが忘れっぽい私のためにここに残しておきます。
ちなみに、サーバーサイドの処理は非同期にする必要はありません。
Activity.kt
private val userInfoRepository = UserInfoRepository()
private val notificationRepository = NotificationRepository()
GlobalScope.launch {
notificationRepository.save(uid, token)
}
var result: List<SaveUserInfo> // SaveUserInfoはデータクラスの名前
GlobalScope.launch {
// 引数のuidと一致するuidのデータを取得
result = userInfoRepository.getUser(uid)
Log.d("TAG", result.toString())
}
こんなかんじでGlobalScope{}
を使って非同期処理を実行できます。
RepositoryはMVVMの記事と全く変わりません。
例えばこんなかんじです。
NotificationRepository.kt
class NotificationRepository {
// uidとトークンを登録
suspend fun save(uid: String?, token: String?): Task<Void> {
return suspendCoroutine { cont ->
val db = FirebaseFirestore.getInstance()
val testNotification = TestNotificationDataClass(uid, token)
val task = db.collection("testNotification")
.document()
.set(testNotification)
Log.d("TOKEN", "about to enter addOnCompleteListener")
task.addOnCompleteListener {
Log.d("TOKEN", "in the addOnCompleteListener")
cont.resume(it)
}
Log.d("TOKEN", "finish addOnCompleteListener")
}
}
suspend fun getUser(uid: String?): List<SaveUserInfo> {
return suspendCoroutine { cont ->
val db = FirebaseFirestore.getInstance()
val task = db.collection("userInfo")
.whereEqualTo("uid", uid)
.get()
task.addOnCompleteListener {
val resultList = task.result!!.toObjects(SaveUserInfo::class.java)
cont.resume(resultList)
}
}
}
}