# #android #firebase #kotlin #google-cloud-firestore #android-recyclerview
Вопрос:
Я пытаюсь получить свои данные в RecyclerView
облачном хранилище данных Firebase. Но когда я это делаю, я получаю следующую ошибку:
исключение java.lang.RuntimeException: Не удалось десериализовать объект. Классные модели.Post не определяет конструктор без аргументов. Если вы используете ProGuard, убедитесь, что эти конструкторы не удалены
Это фрагмент, который я использую:
class forumFragment : Fragment(R.layout.fragment_forum) {
private lateinit var myadapter: MyAdapter
private lateinit var fragmentForumBinding: FragmentForumBinding
private lateinit var userArrayList: ArrayList<itemViewModel>
private lateinit var postDao: postDao
//val mAuth= Firebase.auth.currentUser
val mAuth : FirebaseUser? = FirebaseAuth.getInstance().currentUser
//private lateinit var recyclerView:RecyclerView
private var mDocReference: DocumentReference ?=null
//= FirebaseFirestore.getInstance().collection(/).document()
/*override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// recyclerView = view?.findViewById(R.id.recyclerViewForum)!!
val binding = FragmentForumBinding.inflate(layoutInflater)
fragmentForumBinding = binding
setUpRecyclerView()
}*/
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentForumBinding.bind(view)
fragmentForumBinding = binding
setUpRecyclerView()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view: View = inflater.inflate(R.layout.fragment_forum, container, false)
val fabButtom = view.findViewById<FloatingActionButton>(R.id.fabSave)
fabButtom.setOnClickListener{
if (mAuth !=null){
fabButtom.visibility = View.INVISIBLE
fragmentManager?.beginTransaction()?.addToBackStack(null)?.replace(R.id.forumFragment , addPost())?.commit()
//val navControl = findNavController(R.id.forumFragment)
}
else{
Toast.makeText(activity ,"Please login to make a query!" , Toast.LENGTH_SHORT).show()
}
}
return view
}
private fun setUpRecyclerView() {
// val recyclerView = view?.findViewById<RecyclerView>(R.id.recyclerViewForum)
postDao = postDao()
val postsCollection = postDao.postCollection
val query = postsCollection.orderBy("createdAt" , Query.Direction.DESCENDING)
val firestoreRecyclerOptions = FirestoreRecyclerOptions.Builder<Post>().setQuery(query , Post::class.java).build()
myadapter = MyAdapter(firestoreRecyclerOptions)
fragmentForumBinding.recyclerViewForum.adapter = myadapter
fragmentForumBinding.recyclerViewForum.layoutManager = LinearLayoutManager(activity)
}
override fun onStart() {
super.onStart()
myadapter.startListening()
}
override fun onStop() {
super.onStop()
myadapter.stopListening()
}
}
и models.Post
класс выглядит так:
data class Post (val descrription: String = "",
val createdBy: User = User(),
val currentTime:String = "",
val currentDate:String = "",
val createdAt:Long )
Комментарии:
1. Неясно, используете ли вы Cloud Firestore (по умолчанию), Cloud Firestore в режиме Datatore или Базу данных реального времени, поскольку вы используете эти термины взаимозаменяемо.
2. В будущем при форматировании блоков кода вам нужно будет использовать символ обратной стрелки ` (обычно на клавише тильды
~
) вместо апострофа'
. Один обратный отсчет для встроенного кода, три обратных отсчета (в отдельной строке) для блоков кода.
Ответ №1:
Чтобы Firebase SDK мог преобразовать удаленные данные в нужный класс модели, у него должен быть конструктор без аргументов.
Примечание: Я исправил descrription
description
ниже.
В вашем текущем models.Post
классе у него нет значения по умолчанию для createdAt
:
data class Post (val description: String = "",
val createdBy: User = User(),
val currentTime: String = "",
val currentDate: String = "",
val createdAt: Long ) // <-- missing = 0L
Так и должно быть:
data class Post (val description: String = "",
val createdBy: User = User(),
val currentTime: String = "",
val currentDate: String = "",
val createdAt: Long = 0L )
В качестве альтернативы вы можете иметь следующее объявление для models.Post
:
data class Post (val description: String,
val createdBy: User,
val currentTime: String,
val currentDate: String,
val createdAt: Long) {
// empty constructor for Firebase with dummy data
constructor(): this("", User(), "", "", 0L)
}