Firebase 没有从 onDataChange 方法获取数据
Firebase not getting data from onDataChange method
我知道 Firebase 异步获取数据,我试图在数据加载到我的 recyclerView 适配器之前设置数据,以便它显示在 recyclerview 中。但是当我启动应用程序时,它只获取我最初设置的 "EMPTY" 字符串,而且 firebase 似乎甚至没有进入 onDataChange 方法
CoursesFragment.kt
class CoursesFragment : android.support.v4.app.Fragment(), Contract.View {
val TAG: String = CoursesFragment::class.java.name
val presenter: Contract.Presenter.CoursePresenter = CoursePresenter(this)
var tempDataList: MutableList<String> = mutableListOf()
var dataArray: Array<String> = arrayOf("EMPTY")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
tempDataList = presenter.retrieveCourseNames()
for (i in 0 until tempDataList.size) dataArray[i] = tempDataList[i]
}
override fun onCreateView(inflater: android.view.LayoutInflater?, container: android.view.ViewGroup?,
savedInstanceState: Bundle?): android.view.View? {
// Inflate the layout for this fragment
val v = inflater!!.inflate(R.layout.fragment_courses, container, false)
// Gets cardview widget and sets property
val rView = v.findViewById<RecyclerView>(R.id.recyclerView_courses)
rView.setHasFixedSize(true)
// Creates the 2 column recycler view with the cards
val layoutMan = GridLayoutManager(context, 1)
rView.layoutManager = layoutMan
// Sets up cardview in recycler view
val adapter = CourseRecyclerAdapter(dataArray, presenter)
adapter.notifyDataSetChanged()
rView.adapter = adapter
// actually inflates view
return v
}
// ======================== INTERFACE OVERRIDE METHODS ========================
// CourseContract
override fun showToastMessage(message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
// ======================== USER METHODS ========================
// New Instance Method
companion object {
fun newInstance(page: Int = 0): CoursesFragment {
val argPage: String = "ARG_PAGE"
val args: Bundle = Bundle()
args.putInt(argPage, page)
val fragment = CoursesFragment()
fragment.arguments = args
return fragment
}
}
}
CoursePresenter.kt
class CoursePresenter(val courseView: Contract.View) : Contract.Presenter.CoursePresenter {
val courseInstance = com.alexoladele.cvap.MVP.Course.Model.Course()
override fun retrieveCourseNames(): MutableList<String> {
val returnList: MutableList<String> = mutableListOf()
courseInstance.getCourseNamesFromDB(object : MyCallBack{
override fun doCallback(dbValue: String) {
returnList.add(dbValue)
}
})
return returnList
}
fun testToast() {
courseView.showToastMessage("TOAST TEST")
}
override fun onCourseClick(cardPosition: Int) {
testToast()
}
}
Course.kt
class Course (val name: String = "GENERIC", val content: String = "PLACEHOLDER") : Contract.Model.CourseModel {
val dbReference: DatabaseReference = FirebaseDatabase.getInstance().reference
val courseRef = dbReference.child("Course")
val courseNames = mutableListOf<String>()
override fun getCourseNamesFromDB(callback: MyCallBack) {
courseRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError?) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(p0: DataSnapshot) {
val tempString = p0.value as String
Log.d(TAG, "onDataChange: Value from DB is: $tempString");
callback.doCallback(tempString)
}
})
}
}
interface MyCallBack {
fun doCallback(dbValue: String)
}
编辑: 我已经在 CoursePresenter 中试过了
override fun retrieveCourseNames(dataArray: Array<String>): Array<String> {
// val returnList: MutableList<String> = mutableListOf()
courseInstance.getCourseNamesFromDB(object : MyCallBack{
override fun doCallback(dbValue: String) {
val returnList = mutableListOf<String>()
returnList.add(dbValue)
for (i in 0 until returnList.size)
dataArray[i] = returnList[i]
}
})
return dataArray
}
要解决此问题,您需要在 CoursePresenter.kt
文件中的覆盖 doCallback
函数中声明并使用 val returnList
。这样就不会得到空字符串,因为您等待它才能使用它。
更多信息,你可以从下面post看到我的回答:
我通过完全取消回调来修复它!我在 onDataChange() 方法中设置了 recyclerView 适配器,因此我在获取数据之前没有设置布局,这可能会导致它加载有点慢并且可能违反 MVP,但它有效!!!
我知道 Firebase 异步获取数据,我试图在数据加载到我的 recyclerView 适配器之前设置数据,以便它显示在 recyclerview 中。但是当我启动应用程序时,它只获取我最初设置的 "EMPTY" 字符串,而且 firebase 似乎甚至没有进入 onDataChange 方法
CoursesFragment.kt
class CoursesFragment : android.support.v4.app.Fragment(), Contract.View {
val TAG: String = CoursesFragment::class.java.name
val presenter: Contract.Presenter.CoursePresenter = CoursePresenter(this)
var tempDataList: MutableList<String> = mutableListOf()
var dataArray: Array<String> = arrayOf("EMPTY")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
tempDataList = presenter.retrieveCourseNames()
for (i in 0 until tempDataList.size) dataArray[i] = tempDataList[i]
}
override fun onCreateView(inflater: android.view.LayoutInflater?, container: android.view.ViewGroup?,
savedInstanceState: Bundle?): android.view.View? {
// Inflate the layout for this fragment
val v = inflater!!.inflate(R.layout.fragment_courses, container, false)
// Gets cardview widget and sets property
val rView = v.findViewById<RecyclerView>(R.id.recyclerView_courses)
rView.setHasFixedSize(true)
// Creates the 2 column recycler view with the cards
val layoutMan = GridLayoutManager(context, 1)
rView.layoutManager = layoutMan
// Sets up cardview in recycler view
val adapter = CourseRecyclerAdapter(dataArray, presenter)
adapter.notifyDataSetChanged()
rView.adapter = adapter
// actually inflates view
return v
}
// ======================== INTERFACE OVERRIDE METHODS ========================
// CourseContract
override fun showToastMessage(message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
// ======================== USER METHODS ========================
// New Instance Method
companion object {
fun newInstance(page: Int = 0): CoursesFragment {
val argPage: String = "ARG_PAGE"
val args: Bundle = Bundle()
args.putInt(argPage, page)
val fragment = CoursesFragment()
fragment.arguments = args
return fragment
}
}
}
CoursePresenter.kt
class CoursePresenter(val courseView: Contract.View) : Contract.Presenter.CoursePresenter {
val courseInstance = com.alexoladele.cvap.MVP.Course.Model.Course()
override fun retrieveCourseNames(): MutableList<String> {
val returnList: MutableList<String> = mutableListOf()
courseInstance.getCourseNamesFromDB(object : MyCallBack{
override fun doCallback(dbValue: String) {
returnList.add(dbValue)
}
})
return returnList
}
fun testToast() {
courseView.showToastMessage("TOAST TEST")
}
override fun onCourseClick(cardPosition: Int) {
testToast()
}
}
Course.kt
class Course (val name: String = "GENERIC", val content: String = "PLACEHOLDER") : Contract.Model.CourseModel {
val dbReference: DatabaseReference = FirebaseDatabase.getInstance().reference
val courseRef = dbReference.child("Course")
val courseNames = mutableListOf<String>()
override fun getCourseNamesFromDB(callback: MyCallBack) {
courseRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError?) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(p0: DataSnapshot) {
val tempString = p0.value as String
Log.d(TAG, "onDataChange: Value from DB is: $tempString");
callback.doCallback(tempString)
}
})
}
}
interface MyCallBack {
fun doCallback(dbValue: String)
}
编辑: 我已经在 CoursePresenter 中试过了
override fun retrieveCourseNames(dataArray: Array<String>): Array<String> {
// val returnList: MutableList<String> = mutableListOf()
courseInstance.getCourseNamesFromDB(object : MyCallBack{
override fun doCallback(dbValue: String) {
val returnList = mutableListOf<String>()
returnList.add(dbValue)
for (i in 0 until returnList.size)
dataArray[i] = returnList[i]
}
})
return dataArray
}
要解决此问题,您需要在 CoursePresenter.kt
文件中的覆盖 doCallback
函数中声明并使用 val returnList
。这样就不会得到空字符串,因为您等待它才能使用它。
更多信息,你可以从下面post看到我的回答:
我通过完全取消回调来修复它!我在 onDataChange() 方法中设置了 recyclerView 适配器,因此我在获取数据之前没有设置布局,这可能会导致它加载有点慢并且可能违反 MVP,但它有效!!!