Firebase RTDB: Das Lesen von Daten mithilfe der Paginierung nimmt viel Zeit in Anspruch

Post a reply

Smilies
:) :( :oops: :chelo: :roll: :wink: :muza: :sorry: :angel: :read: *x) :clever:
View more smilies

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Firebase RTDB: Das Lesen von Daten mithilfe der Paginierung nimmt viel Zeit in Anspruch

by Guest » 03 Jan 2025, 16:26

Ich benötige ein großes Datenpaket (10 MB) von RTDB. Alle Daten werden im Knoten „stations“ gespeichert. Wenn ich alle Daten in einer einzigen Anfrage erhalte, stürzt meine Android-App manchmal mit der Fehlermeldung „OutOfMemory“ ab. Ich muss also paginiertes Lesen verwenden, habe aber ein Problem damit.
Die Anforderung, vollständige Daten von Stationen zu lesen dauert in meinem Fall etwa 10–12 Sekunden. Wenn ich jedoch mehrere Anfragen (Paginierung) stelle und 2 MB für eine Seite lese, dauert jede Anfrage ebenfalls etwa 10 Sekunden. Dadurch erhöhte sich die Gesamtzeit zum Abrufen der Stationsdaten von 10 Sekunden (Einzellesevorgang) auf 50 Sekunden (Seitenlesevorgang). Kann ich die Paginierung beschleunigen? Danke.
Image

Code: Select all

private fun fetchDayStationsPaged(dayTag: String, lastNodeId: String? = null, stations: MutableList = mutableListOf(), callback: (data: List, errorMessage: LoadError?) -> Unit){
val path = String.format(TimelineManager.KEY_TIMELINE_STATIONS, dayTag)

val query = if (lastNodeId == null)
database
.getReference(path)
.orderByKey()
.limitToFirst(2000) //1 node takes approx 1KB
else
database
.getReference(path)
.orderByKey()
.startAfter(lastNodeId)
.limitToFirst(2000)

Timber.d("loader recursion stations $dayTag/${stations.size}")

fetchDayStations(query) { data, errorMessage ->
if (errorMessage == LoadError.NotExist)
callback(stations, null)
else if (errorMessage != null)
callback(emptyList(), errorMessage)
else {
stations.addAll(data)
fetchDayStationsPaged(dayTag, data.last().nodeId, stations, callback)
}
}
}

private var loaderDisposable: Disposable? = null

private fun fetchDayStations(ref: Query, callback: (data: List, errorMessage: LoadError?) -> Unit){

loaderDisposable?.dispose()
loaderDisposable = FirebaseHelper
.dbReadAsSingle(ref)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.doOnDispose {
callback(emptyList(), LoadError.Cancelled)
}
.subscribe ({ snapshot ->
if (snapshot.exists()) {
val stations = mutableListOf()
snapshot.children.forEach { item ->
item.getValue(StationCloud::class.java)?.also { station ->
stations.add(station.copy(nodeId = item.key))
}
}
Timber.d("loader fetchDayStations stations size = ${stations.size}")
callback(stations.toList(), null)
} else
callback(emptyList(), LoadError.NotExist)
}, {
Timber.e(it)
callback(emptyList(), LoadError.CantGet)
})
}

private fun dbReadAsSingle(ref: Query): Single {
return Single.create { emitter ->
ref.get().addOnCompleteListener { task ->
Timber.d("runQueryCloudFirst task succeed = ${task.isSuccessful}")
if (task.isSuccessful && emitter.isDisposed.not()){
Timber.d("runQueryCloudFirst children size = ${task.result.childrenCount}")
emitter.onSuccess(task.result)
} else
task.exception?.also {
//todo check a bug: timeout exception doesn't work when offline
//https://github.com/firebase/firebase-android-sdk/issues/5771
Timber.e(it, "runQueryCloudFirst")
emitter.onError(it)
}
}
}
}

Top