Я пытаюсь получить поле «имя» из базы данных Firestore с помощью двух разных процессов. В обоих процессах я использую вспомогательный класс для получения данных как Flow[*]>, а затем в ViewModel собираю их и покрываю как LiveData. Но в одном случае я получаю правильный результат, а в другом — нет. Я не знаю причину такого поведения. Пожалуйста, помогите мне объяснить это.
Я предоставлю вам важную часть моего вспомогательного класса, viewModel в обоих случаях. И соответствующее сообщение logcat для обоих случаев.
Случай 1 (получение пустого или нулевого значения)->
val firestoreHelperForToken = FirestoreHelperForToken()
private val _getAllNames = MutableLiveData()
val getAllNames : LiveData get() = _getAllNames
init {
//subscribe to a topic to broadcast the message
viewModelScope.launch {
firestoreHelperForToken.fetchAllNames.collect { namesList ->
_getAllNames.postValue(namesList)
// Log inside the collect block to ensure that the data is fetched
Log.d("ChatViewModel", "List from Firestore: $namesList")
// Small delay to ensure data sync if needed
delay(100)
// Check if list is not null or empty and log it
if (!namesList.isNullOrEmpty()) {
Log.d("ChatViewModel", "Valid list received: $namesList")
} else {
Log.d("ChatViewModel", "Empty list received.")
}
}
// Log outside of the collect block after it finishes fetching
Log.d("ChatViewModel", "List outside the collect block: ${getAllNames.value}")
}}
class FirestoreHelperForToken {
private val TAG = "FirestoreHelperForToken"
private val _db = Firebase.firestore
val fetchAllNames: Flow[*]> = channelFlow {
Log.d(TAG, "Setting up addSnapshotListener")
_db.collection("tokens")
.addSnapshotListener { snapshot, e ->
if (e != null) {
Log.w(TAG, "Listen failed with error: $e")
return@addSnapshotListener
}
if (snapshot == null || snapshot.isEmpty) {
Log.d(TAG, "Snapshot is null or empty.")
trySend(emptyList()) // Emit empty list if no documents are found
return@addSnapshotListener
}
val namesList = mutableListOf()
Log.d(TAG, "Snapshot size: ${snapshot.size()}")
for (document in snapshot.documents) {
val name = document.getString("name")
name?.let {
namesList.add(it)
}
}
try {
Log.d(TAG, "Names list: $namesList")
trySend(namesList) // Emit the list of names
} catch (sendError: Exception) {
Log.e(TAG, "Error while sending names list: ${sendError.message}")
}
}
}.flowOn(Dispatchers.IO)
}
viewModelScope.launch {
Log.d("ChatViewModel", "List outside the collect block: ${getAllNames.value}")
firestoreHelperForToken.getNamesFlow()
.collect { namesList ->
_getAllNames.postValue(namesList)
// Log inside the collect block to ensure that the data is fetched
Log.d("ChatViewModel", "List from Firestore: $namesList")
}
Я пытаюсь получить поле «имя» из базы данных Firestore с помощью двух разных процессов. В обоих процессах я использую вспомогательный класс для получения данных как Flow[*]>, а затем в ViewModel собираю их и покрываю как LiveData. Но в одном случае я получаю правильный результат, а в другом — нет. Я не знаю причину такого поведения. Пожалуйста, помогите мне объяснить это. Я предоставлю вам важную часть моего вспомогательного класса, viewModel в обоих случаях. И соответствующее сообщение logcat для обоих случаев. Случай 1 (получение пустого или нулевого значения)-> [list]
ViewModel (важная часть)-> [code]val firestoreHelperForToken = FirestoreHelperForToken() private val _getAllNames = MutableLiveData() val getAllNames : LiveData get() = _getAllNames
init {
//subscribe to a topic to broadcast the message viewModelScope.launch {
firestoreHelperForToken.fetchAllNames.collect { namesList -> _getAllNames.postValue(namesList) // Log inside the collect block to ensure that the data is fetched Log.d("ChatViewModel", "List from Firestore: $namesList")
// Small delay to ensure data sync if needed delay(100)
// Check if list is not null or empty and log it if (!namesList.isNullOrEmpty()) { Log.d("ChatViewModel", "Valid list received: $namesList") } else { Log.d("ChatViewModel", "Empty list received.") } }
// Log outside of the collect block after it finishes fetching Log.d("ChatViewModel", "List outside the collect block: ${getAllNames.value}") }} [/code]
[*]HelperClass (важная часть)->
[/list][code]class FirestoreHelperForToken { private val TAG = "FirestoreHelperForToken" private val _db = Firebase.firestore val fetchAllNames: Flow[*]> = channelFlow { Log.d(TAG, "Setting up addSnapshotListener")
_db.collection("tokens") .addSnapshotListener { snapshot, e -> if (e != null) { Log.w(TAG, "Listen failed with error: $e") return@addSnapshotListener }
if (snapshot == null || snapshot.isEmpty) { Log.d(TAG, "Snapshot is null or empty.") trySend(emptyList()) // Emit empty list if no documents are found return@addSnapshotListener }
val namesList = mutableListOf() Log.d(TAG, "Snapshot size: ${snapshot.size()}")
for (document in snapshot.documents) { val name = document.getString("name") name?.let { namesList.add(it) } } try { Log.d(TAG, "Names list: $namesList") trySend(namesList) // Emit the list of names } catch (sendError: Exception) { Log.e(TAG, "Error while sending names list: ${sendError.message}") } }
}.flowOn(Dispatchers.IO)
} [/code] 3. Логи в данном случае -> [code]2024-10-06 10:57:26.586 1389-1422 FirestoreHelperForToken com.example.fcmpractice D Setting up addSnapshotListener 2024-10-06 10:57:27.296 1389-1389 ChatViewModel com.example.fcmpractice D List outside the collect block: null 2024-10-06 10:57:27.299 1389-1389 FirestoreHelperForToken com.example.fcmpractice D Snapshot size: 17 2024-10-06 10:57:27.312 1389-1389 FirestoreHelperForToken com.example.fcmpractice D Names list: [mona, abhijit, mahesh, raka, ritu, ranna, jodha, biru, madhav, babu, rajat, sujal, mauni, meme, raghav, mamu, nammy] [/code] Случай 2: получение правильного списка (все то же самое, только небольшое функциональное изменение) -> [list] HelperClass-> [code] fun getNamesFlow() : Flow = callbackFlow { val collectionRef = _db.collection("tokens") val listner = collectionRef.addSnapshotListener { snapshot, error -> if (error != null) { close(error) return@addSnapshotListener } if (snapshot != null && !snapshot.isEmpty){ val nameList = snapshot.documents.map { it.getString("name") ?: "" } trySend(nameList) }else{ trySend(emptyList()) } } awaitClose { listner.remove() } }
[/code] 2. Модель просмотра -> [code]viewModelScope.launch { Log.d("ChatViewModel", "List outside the collect block: ${getAllNames.value}") firestoreHelperForToken.getNamesFlow() .collect { namesList -> _getAllNames.postValue(namesList) // Log inside the collect block to ensure that the data is fetched Log.d("ChatViewModel", "List from Firestore: $namesList") } [/code]
[/list]
3. Ведение журнала-> [code]2024-10-06 11:03:12.399 1851-1851 ChatViewModel com.example.fcmpractice D List outside the collect block: null 2024-10-06 11:03:13.103 1851-1851 ChatViewModel com.example.fcmpractice D List from Firestore: [mona, abhijit, mahesh, raka, ritu, ranna, jodha, biru, madhav, babu, rajat, sujal, mauni, meme, raghav, mamu, nammy] [/code] Смиренно прошу подробно объяснить причину таких разных результатов.
Мое приложение для Android использует Firebase Firestore. У меня есть коллекция пользователей и коллекция достижений. У каждого достижения есть список владельцев, который является идентификатором документа из коллекции пользователей. В моей...
В настоящее время я исследую аварийный дамп с клиентского сайта, так как не могу отладить его в режиме реального времени. Короче говоря, приложение вылетает с кодом исключения 0xC015000F, который указывает на то, что «деактивируемый контекст...
Я уверен, что что-то пропустил. В определенном проекте мне нужно проверить, является ли строка нулевой или пустой.
Есть ли более простой способ написать это?
if (myString == null || myString == )
{
...
Мой раскрывающийся список привязан к базе данных, я хочу, чтобы он позволял выбирать значения NULL. Поэтому, когда он выбран, в таблицу ничего не попадает. Прямо сейчас это работает, если бы я установил целое число, но я не хочу, чтобы это работало...
Веб-страница:
Сейчас я пробую скрап-драматургию. Я также пробовал использовать селен, но безрезультатно.
Я могу получить доступ к телу и корневому элементу div. Я понимаю, что страница динамически загружается с использованием Java, но я не могу...