使用Kotlin从Firebase数据库检索数据的问题

vwkv1x7d  于 2023-10-23  发布在  Kotlin
关注(0)|答案(1)|浏览(145)

我正在使用Kotlin开发一个Android应用程序,我面临着在屏幕上显示从Firebase实时数据库检索到的数据的问题。

package com.kader.foxycode_casestudy.Fragment

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import com.kader.foxycode_casestudy.Models.WordModel
import com.kader.foxycode_casestudy.R

class WordFragment : Fragment() {

    private lateinit var textViewWord: TextView
    private lateinit var buttonPrevious: ImageView
    private lateinit var buttonNext: ImageView

    private lateinit var databaseReference: DatabaseReference

    private var words: MutableList<WordModel> = mutableListOf()

    private var currentWordIndex: Int = 0

    private var currentLanguage: String = "English"

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_word, container, false)

        textViewWord = view.findViewById(R.id.textViewWord)
        buttonPrevious = view.findViewById(R.id.buttonPrevious)
        buttonNext = view.findViewById(R.id.buttonNext)

        val categoryId: String? = arguments?.getString("categoryId")
        if (categoryId != null) {
            Log.d("WordFragment", "CategoryId: $categoryId")
            // categoryId null değilse burada kullanabilirsiniz
            databaseReference =
                FirebaseDatabase.getInstance("https://foxycodecasestudy-default-rtdb.europe-west1.firebasedatabase.app")
                    .getReference("categories")
                    .child(categoryId)
                    .child("words")
            Log.d("WordFragment", "Database reference: $databaseReference")

            // Previous ve Next butonlarına tıklama dinleyicilerini ekle
            buttonPrevious.setOnClickListener {
                Log.d("WordFragment", "Previous button clicked")
                showPreviousWord()
            }

            buttonNext.setOnClickListener {
                Log.d("WordFragment", "Next button clicked")
                showNextWord()
            }

            // Veritabanından kelimeleri çek
            fetchWords()
        } else {
            // categoryId null ise burada uygun bir şekilde işlem yapabilirsiniz
            Log.e("WordFragment", "CategoryId is null.")
        }

        return view
    }

    private fun fetchWords() {
        // Veritabanındaki kelimeleri dinle
        databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                Log.d("WordFragment", "OnDataChange.")
                if (dataSnapshot.exists()) {
                    for (wordSnapshot in dataSnapshot.children) {
                        Log.d("WordFragment", "Word: ${wordSnapshot.value}")
                    }

                    if (words.isNotEmpty()) {
                        // Veriler başarıyla çekildiyse, words listesini temizle
                        words.clear()

                        for (wordSnapshot in dataSnapshot.children) {
                            val id = wordSnapshot.key
                            val enWord = wordSnapshot.child("en").getValue(String::class.java)
                            val trWord = wordSnapshot.child("tr").getValue(String::class.java)

                            if (id != null && enWord != null && trWord != null) {
                                val word = WordModel(id, enWord, trWord)
                                words.add(word)
                            }
                        }

                        Log.d("WordFragment", "Words list size: ${words.size}")

                        // Eğer kelimeler varsa, ilk kelimeyi göster
                        if (words.isNotEmpty()) {
                            showWord(currentWordIndex)
                        }
                    }
                } else {
                    Log.e("WordFragment", "DataSnapshot is empty.")
                }
            }

            override fun onCancelled(databaseError: DatabaseError) {
                val errorMessage = databaseError.message
                Log.e("WordFragment", "FirebaseError: $errorMessage")
            }
        })
    }

    private fun showWord(index: Int) {
        Log.d("WordFragment", "showWord called with index: $index")

        if (index in 0 until words.size) {
            val word = words[index]

            // Log ekleyerek kontrol et
            Log.d("WordFragment", "Word Index: $index")
            Log.d("WordFragment", "Word ID: ${word.id}")
            Log.d("WordFragment", "Word English: ${word.en}")
            Log.d("WordFragment", "Word Turkish: ${word.tr}")

            // İngilizceyi göster
            if (currentLanguage == "English") {
                textViewWord.text = word.en
            } else if (currentLanguage == "Turkish") {
                // Türkçeyi göster
                textViewWord.text = word.tr
            }

            Log.d("WordFragment", "Showing word: ${textViewWord.text}")
        } else {
            Log.e("WordFragment", "Invalid word index: $index")
        }
    }




    private fun showPreviousWord() {
        if (currentWordIndex > 0) {
            currentWordIndex--
            showWord(currentWordIndex)
        }
    }

    private fun showNextWord() {
        if (currentWordIndex < words.size - 1) {
            currentWordIndex++
            showWord(currentWordIndex)
        }
    }
}
package com.kader.foxycode_casestudy.Models

data class WordModel(
    val id: String? = null,
    val en: String? = null,
    val tr: String? = null
)

我成功地从数据库中获取数据,但在屏幕上显示此数据时遇到问题。当我将检索到的数据分配给名为textViewWord的TextView时,屏幕上没有任何变化。
我已通过日志消息确认已成功从Firebase数据库检索数据。
我已经检查了XML文件中textViewWord的定义。

{
  "categories": {
    "category1": {
      "en": "Family",
      "tr": "Aile",
      "words": {
        "en": [
          "Mother",
          "Father",
          "Child",
          "Sibling",
          "Family",
          "House"
        ],
        "tr": [
          "Anne",
          "Baba",
          "Çocuk",
          "Kardeş",
          "Aile",
          "Ev"
        ]
      }
    },
    "category10": {
      "en": "Nature",
      "tr": "Doğa",
      "words": {
        "en": [
          "Forest",
          "Mountain",
          "Lake",
          "Flower",
          "Sun",
          "Sea"
        ],
        "tr": [
          "Orman",
          "Dağ",
          "Göl",
          "Çiçek",
          "Güneş",
          "Deniz"
        ]
      }
    }
  }
}
pgky5nke

pgky5nke1#

由于您正在加载categories/$categoryId/words,因此onDataChange中的DataSnapshot将包含以下内容:

"words": {
  "en": [
    "Mother",
    "Father",
    "Child",
    "Sibling",
    "Family",
    "House"
  ],
  "tr": [
    "Anne",
    "Baba",
    "Çocuk",
    "Kardeş",
    "Aile",
    "Ev"
  ]
}

如果循环遍历此节点的子节点,就像您的代码对for (wordSnapshot in dataSnapshot.children)所做的那样,您首先会获得一个带有en键和一个值列表/数组的快照,然后是一个带有tr键和另一个值列表的快照。这也是日志输出显示的内容。
但是您的代码似乎假定在每个wordSnapshot下都有一整套语言。但是,这与您的数据结构不匹配,因此wordSnapshot.child("en").getValue(String::class.java)不会返回任何内容-因为wordSnapshot下没有en节点。
据我所知,应该是:

databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        Log.d("WordFragment", "OnDataChange.")
        if (dataSnapshot.exists()) {
            ...
            for (languageSnapshot in dataSnapshot.children) {
                val languageId = languageSnapshot.key
                for (wordSnapshot in languageSnapshot.children) {
                    val wordValue = wordSnapshot.getValue(String::class.java)
                    Log.d(languageId, wordValue)
                }
            }

            ...

        } else {
            Log.e("WordFragment", "DataSnapshot is empty.")
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        val errorMessage = databaseError.message
        Log.e("WordFragment", "FirebaseError: $errorMessage")
    }
})

相关问题