Firebase RTDB: Das Lesen von Daten mithilfe der Paginierung ist zu langsamAndroid

Forum für diejenigen, die für Android programmieren
Guest
 Firebase RTDB: Das Lesen von Daten mithilfe der Paginierung ist zu langsam

Post by Guest »

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 zum Lesen vollständiger Daten von Stationen 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.
Struktur:
Image

Regeln:
Image

Paginierungslogik:

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)
}
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post