Я попытался получить данные из Firestore, используя библиотеку подкачки. Приложение работает, но не может получить данные из базы данных. Я не могу найти ошибки в коде. Если кто-нибудь может помочь. Ваша помощь приветствуется. Ниже приведен код.
Модель Класс Примечание
import com.google.firebase.firestore.Exclude
import com.google.firebase.firestore.IgnoreExtraProperties
@IgnoreExtraProperties
data class Note (
@Transient
@get:Exclude
var id :String? = "",
var rank:Int,
var name :String? = "null"
)
Репозиторий
import android.util.Log
import androidx.paging.ItemKeyedDataSource
import com.google.firebase.firestore.FirebaseFirestore
import com.karuneshpalekar.firestorepagination.models.Note
class DataRepository {
companion object {
const val TAG = "DataRepo"
}
val db = FirebaseFirestore.getInstance()
fun getData(
startRank: Int,
size: Int,
callback: ItemKeyedDataSource.LoadCallback<Note>
) {
db.collection("record").whereGreaterThan("rank", startRank)
.limit(size.toLong())
.addSnapshotListener { snapshot, e ->
if (e != null) {
Log.w(TAG, "Error:$e")
}
val items = mutableListOf<Note>()
if (snapshot != null) {
for (notes in snapshot) {
items.add(notes.toObject(Note::class.java))
Log.i(TAG, "Great")
}
if (items.size == 0) {
return@addSnapshotListener
}
if (callback is ItemKeyedDataSource.LoadInitialCallback) {
callback.onResult(items, 0, items.size)
} else {
callback.onResult(items)
}
}
}
}
}
DataSource
import androidx.paging.DataSource
import androidx.paging.ItemKeyedDataSource
import com.karuneshpalekar.firestorepagination.models.Note
class SourceData(private val dataRepository: DataRepository) : ItemKeyedDataSource<Int, Note>() {
class Factory(private val mydataRepository: DataRepository) :
DataSource.Factory<Int, Note>() {
override fun create(): DataSource<Int, Note> =
SourceData(mydataRepository)
}
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Note>) {
dataRepository.getData(0,params.requestedLoadSize,callback)
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Note>) {
dataRepository.getData(params.key,params.requestedLoadSize,callback)
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Note>) {
// dataRepository.getData(params.key,params.requestedLoadSize,callback)
}
override fun getKey(item: Note): Int = item.rank
}
ViewModel
class DataViewModel(dataRepository: DataRepository) : ViewModel() {
private val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(10)
.setPageSize(20)
.build()
val records: LiveData<PagedList<Note>> =
LivePagedListBuilder<Int, Note>(SourceData.Factory(dataRepository), config).build()
}
Адаптер
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.karuneshpalekar.firestorepagination.R
import com.karuneshpalekar.firestorepagination.models.Note
class DataAdapter : PagedListAdapter<Note, DataAdapter.DataViewHolder>(
object : DiffUtil.ItemCallback<Note>() {
override fun areItemsTheSame(oldItem: Note, newItem: Note): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Note, newItem: Note): Boolean = oldItem == newItem
}
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
return DataViewHolder(view)
}
override fun onBindViewHolder(holder: DataViewHolder, position: Int) {
val notes = getItem(position)
if (notes != null) {
holder.bind(notes)
}
}
class DataViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val text_name by lazy { view.findViewById<TextView>(R.id.text_view_name) }
fun bind(note: Note) {
text_name.text = note.name
}
}
}
Фрагмент, отображающий Recyclerview
class Display : Fragment() {
private lateinit var viewModel: DataViewModel
private lateinit var factory: DataFactoryRepository
private val adapter = DataAdapter()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
if (::factory.isInitialized) {
viewModel = ViewModelProviders.of(this, factory).get(DataViewModel::class.java)
}
return inflater.inflate(R.layout.fragment_recyclerview, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
recycler_view.adapter = adapter
if (::viewModel.isInitialized) {
viewModel.records.observe(viewLifecycleOwner, Observer {
adapter.submitList(it)
})
}
floating_btn_add.setOnClickListener {
DialogFragment().show(childFragmentManager, "")
}
}
}
ViewModel Factory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.IllegalArgumentException
class DataFactoryRepository(private val dataRepository: DataRepository) :
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(DataViewModel::class.java)) {
return DataViewModel(dataRepository) as T
}
throw IllegalArgumentException("ViewModel Class Not Created")
}
}
Трассировка стека говорит следующее
2020-03-29 14:55:29.677 1752-2663/? E/GnssHAL_GnssInterface: gnssSvStatusCb: a: input svInfo.flags is 8
2020-03-29 14:55:29.677 1752-2663/? E/GnssHAL_GnssInterface: gnssSvStatusCb: b: input svInfo.flags is 8
2020-03-29 14:55:29.698 3031-3987/com.google.android.apps.nexuslauncher E/ActivityThread: Failed to find provider info for com.google.android.apps.wellbeing.api
2020-03-29 14:55:29.717 2122-2161/system_process E/system_server: Invalid ID 0x00000000.
2020-03-29 14:55:29.918 9371-9371/? E/storepaginatio: Unknown bits set in runtime_flags: 0x8000
2020-03-29 14:55:30.655 2122-2122/system_process E/LoadedApk: Unable to instantiate appComponentFactory
java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[],nativeLibraryDirectories=[/system/priv-app/GoogleSdkSetup/lib/x86, /system/lib, /system/product/lib, /system/lib, /system/product/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.LoadedApk.createAppFactory(LoadedApk.java:256)
at android.app.LoadedApk.updateApplicationInfo(LoadedApk.java:370)
at android.app.ActivityThread.handleDispatchPackageBroadcast(ActivityThread.java:5951)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1941)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at com.android.server.SystemServer.run(SystemServer.java:541)
at com.android.server.SystemServer.main(SystemServer.java:349)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:908)
2020-03-29 14:55:30.674 1752-2663/? E/GnssHAL_GnssInterface: gnssSvStatusCb: a: input svInfo.flags is 8
2020-03-29 14:55:30.674 1752-2663/? E/GnssHAL_GnssInterface: gnssSvStatusCb: b: input svInfo.flags is 8
2020-03-29 14:55:30.842 3815-3858/com.google.android.googlequicksearchbox:search E/MicroDetectionWorker: Stale runnable..ignoring
2020-03-29 14:55:31.002 1779-1981/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
2020-03-29 14:55:31.002 1779-1981/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
Приведенный выше код используется для реализации Paging Library + Firestore.