Why doesn't this function give me a true result? - android

I'm doing a duplicate registration check on this page. When the function is running, I can see how many entries are from the same record. I saw this with println. but I cannot get this number with this function. the number returns zero. If I think it is my default value.
How can I solve this problem, can you help me?
open class Mukerrermi(var english: String,var turkce:String,var context: Context){
var sonuc:Int=0
fun kontrolEt(): Int {
val parsUser= ParseUser.getCurrentUser().email
println("Mük "+parsUser.toString())
val query= ParseQuery.getQuery<ParseObject>("Kelimeler")
query.whereEqualTo("User",parsUser.toString())
val query1= ParseQuery.getQuery<ParseObject>("Kelimeler")
query.whereContains("Eng",english)
query1.whereContains("Turk",turkce)
val querys=ArrayList<ParseQuery<ParseObject>>()
querys.add(query)
querys.add(query1)
val mainQuery = ParseQuery.or<ParseObject>(querys)
mainQuery.findInBackground { objects, e ->
if (e != null) {
Toast.makeText(context, e.localizedMessage.toString(), Toast.LENGTH_LONG).show()
sonuc= objects.size
} else {
sonuc= objects.size
println("Bulunan "+sonuc.toString())
}
}
println("Bulunan kayıtlar "+sonuc.toString())
return sonuc

Related

Extract Data from firebase

Unable to extract information from the datasnapshot received from firebase.
Currently, I am able to get the dataSnapshot from firebase, but I am having problems extracting the information from it.
In the example below I have a lobby with the code "81MUB" and inside I have a list of players (only using one player in the example). Data from FireBase
{
"81MUB": [
{
"name": "Alejandro",
"points": 0
}
]
}
Data Class
data class Player(
val name: String,
val points: Int
)
Listener
fun getCode(): String {
val index = ('A'..'Z') + ('1'..'9')
var code = ""
for (i in 0..4){
code += index[Random().nextInt(index.size)]
}
return code
}
class MviewModel : ViewModel() {
private val _Players: MutableLiveData<MutableList<Player>> =
MutableLiveData(mutableListOf<Player>(Player("Alejandro", 0)))
private var _LobbyCode: String = ""
private val dataBase = FirebaseDatabase.getInstance()
fun getPlayer(): MutableLiveData<MutableList<Player>> = _Players
fun createLobby() {
_LobbyCode = getCode()
}
fun listener() {
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
}
override fun onCancelled(databaseError: DatabaseError) {
// Getting Post failed, log a message
}
}
dataBase.reference.child(_LobbyCode).addValueEventListener(postListener)
}
}
Any tips?
Each time you call getCode() you are generating a new random code. When reading data, you always use the exact same code that exists in the database. So in code, it should look like this:
val db = Firebase.database.reference
val codeRef = db.child("81MUB")
codeRef.get().addOnCompleteListener {
if (it.isSuccessful) {
val snapshot = it.result
val name = snapshot.child("name").getValue(String::class.java)
val points = snapshot.child("points").getValue(Long::class.java)
Log.d("TAG", "$name/$points")
} else {
Log.d("TAG", error.getMessage()) //Never ignore potential errors!
}
}
The result in the logcat will be:
Alejandro/0
If you however want to map the 81MUB node into an object of type Player, then your data class should look like this:
data class Player(
val name: String? = null,
val points: Int? = null
)
And in code:
val db = Firebase.database.reference
val codeRef = db.child("81MUB")
codeRef.get().addOnCompleteListener {
if (it.isSuccessful) {
val snapshot = it.result
val player = snapshot.getValue(Player::class.java)
Log.d("TAG", "${player.name}/${player.points}")
} else {
Log.d("TAG", error.getMessage()) //Never ignore potential errors!
}
}
Which will produce the exact same output as above.
You might also take into consideration, using the DatabaseReference#push() method which:
Create a reference to an auto-generated child location. The child key is generated client-side and incorporates an estimate of the server's time for sorting purposes.
Instead of using your codes.

How to map aggregated data from Firestore document back to a Kotlin List

Would like to reduce the number of reads in my app with Firestore. So I created a document in my collection with the following structure to hold values for 10 "records", that I will get with a single read - since the size of this document is pretty decent, no worries about the 1MB limit size for a single document. I am updating the content of this document with cloud functions.
name of collection: helperz
name of document: top10
field name in top10: tresholdCounter - this I need to check if a single map should be added to top10 or not
field name in top10: top10 . . array of maps
helperz/top10/tresholdCounter
helperz/top10/top10/0/author
helperz/top10/top10/0/name
helperz/top10/top10/0/url
helperz/top10/top10/1/author
helperz/top10/top10/1/name
helperz/top10/top10/1/url
helperz/top10/top10/2/author
helperz/top10/top10/2/name
helperz/top10/top10/2/url
helperz/top10/top10/3/author
helperz/top10/top10/3/name
helperz/top10/top10/3/url
helperz/top10/top10/4/author
helperz/top10/top10/4/name
helperz/top10/top10/4/url
..
helperz/top10/top10/10/author
helperz/top10/top10/10/name
helperz/top10/top10/10/url
I have a data class . . like this:
data class MyClass(
var name: String? = null,
var url: String? = null,
var author: String? = null,
var counter: Int = 0,
var free: Boolean? = false,
var global: Boolean?=true,
var poses: ArrayList<MyPoze>? = null,
var docId: string? = null,
var category: ArrayList<String>? = null,
#get:PropertyName(CREATED)
#set:PropertyName(CREATED)
#ServerTimestamp var created: Timestamp? = null
)
There are some other fields as well, but for the purpose of this problem, that should be ok.
I have a code for retrieving data from Firestore (in my viewModel):
private fun getHelperzTop10() = viewModelScope.launch {
Log.d("MP23", "getHelperzTop10")
val docRef = db.collection("helperz").document("top10")
docRef.addSnapshotListener { snapshot, e ->
if (e != null) {
Log.w("MP23", "Listen failed.", e)
return#addSnapshotListener
}
if (snapshot != null && snapshot.exists()) {
val docSize = firestoreDocument.getSize(snapshot);
Log.d("MP23","docSize in Bytes: $docSize, in KB: ${docSize * 0.001}, in MB: ${docSize * 0.000001}"
)
val top10 = snapshot.data
Log.d("MP23", top10!!::class.simpleName.toString() )
if ("top10" in keys) {
val top10arr = top10["top10"] as ArrayList<MyClass>
Log.d("MP23", "we have top10 in top10")
Log.d("MP23", top10arr!!::class.simpleName.toString())
Log.d("MP23", top10arr.toString())
//// 👇 PROBLEM HERE ///
// here I need somehow to cast this array of maps as MyClass, but I am getting error:
// java.util.ArrayList cannot be cast to java.lang.MyClass
// or
// java.util.ArrayList cannot be cast to java.lang.Object[] - with some other versions
}
} else {
Log.d("MP23", "Current data: null")
}
}
}
If someone can suggest how can I cast result to MyClass, that would be great. In normal situation (where I have documents that I query against) nicely as single docs, I can easily do:
val singleRec = singleRec.toObject(MyClass::class.java)
If you want to get the top10 array as a List<MyClass>, the simplest solution that I can think of would be to create another class:
data class Document(
var top10: MutableList<MyClass>? = null
)
And read the content of the document like this:
docRef.get().addOnCompleteListener {
if (it.isSuccessful) {
val snapshot = it.result
snapshot?.let {
val document = snapshot.toObject(Document::class.java)
document?.let {
val top10 = document.top10
top10?.let {
for (myClass in top10) {
val name = myClass.name
Log.d("TAG", "$name")
}
}
}
}
} else {
it.exception?.message?.let { message ->
Log.d("TAG", message) //Never ignore potential errors!
}
}
}
I will also recommend you read the following resource for a better understanding:
How to map an array of objects from Cloud Firestore to a List of objects?

Android Kotlin RxJava when first failed, then run second single

New to RxJava.
I want to get UserInfo from cache or Net. when cache is null, then get it from net.
I use two RxJava.Single, try to use concatWith, but it doesn't work.
cacheX is a Single<UserInfo> , when null throw DatabaseItemNotFoundException(self defined.)
userService.getUserInfo is also a Single<UserInfo>
fun getUserInfoFromCacheOrServer(
context: Context, disposables: CompositeDisposable,
token: String?, forceUpdate: Boolean, callback: (UserInfo?, String?) -> Unit
) {
if (token.isNullOrBlank())
return
var save = false
val cacheRepository = CacheRepository(context)
val cacheX = Single.fromCallable {
val cache = if (forceUpdate) null else
cacheRepository.getCacheRx<UserInfo>(KEY_USER_INFO, null, 24 * 60)
Timber.d("cache=$cache")
cache ?: let {
save = true
throw DatabaseItemNotFoundException("cache is null or expired.")
}
}
// I want to get UserInfo from net, when cache is null.
val net = userService.getUserInfo(token.trim()).also { save = true }
cacheX.concatWith(net)
RxJavaResponseUtils.processSingle("getUserInfo", disposables, cacheX) { info, errMsg ->
if (save && info != null) {
cacheRepository.saveCache(KEY_USER_INFO, null, info)
}
callback(info, errMsg)
}
}

How to retrieve data from nested array of maps in Firestore (Kotlin) for RecyclerView

I would like to ask for help on how to retrieve data from Firestore for nested Array of Maps called "cities" into MutableList , which I then want to insert into recycler view, where the data from the “regions” are for the header and data “cities” for the regular list items.
Data for regions: MutableList , when I follow the procedure https://medium.com/firebase-tips-tricks/how-to-map-an-array-of-objects-from-cloud-firestore-to-a-list -of-objects-122e579eae10 by Alex Mamo, got fine, but data for: cities: MutableList , according same approach, is null (unable to retrive).
Can you please advise how to get data for “cities”?
P.s. somewhere I read the recommendation to iterate over "cities", but I have no idea how, please go straight for an example (ideally in Kontlin).
Code:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
…..
regionsRef.get().addOnCompleteListener { document ->
if (document.isSuccessful()) {
val documentSnapshot = document.result
// Retrieve array of maps for „regions“
val regions = documentSnapshot.toObject(RegionDocument::class.java)?.regions
// Retrieve array of maps for „cities“
val cities = documentSnapshot.toObject(CityDocument::class.java)?.cities
…
}
}
Data classes for object City:
data class City(
val cityNumber: Long? = null,
val cityName: String? = "" )
data class CityDocument(
var cities: MutableList<City>? = null)
Firestore structure:
To be able to get the data that corresponds to your document structure, you need three classes:
class Document {
var regions: MutableList<Region>? = null
}
class Region {
var cities: MutableList<City>? = null
var regionName: String? = null
var regionNumber: Long? = null
}
class City {
var cityName: String? = null
var cityNumber: Long? = null
}
And below you can find a solution for reading all cities:
val db = FirebaseFirestore.getInstance()
val docIdRef = db.collection("collName").document("docId")
docIdRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val document = task.result
if (document != null) {
val doc = document.toObject(Document::class.java)
if (doc != null) {
val regions = doc.regions
if (regions != null) {
for (region in regions) {
val cities = region.cities
//Do what you need to to do with your List<City>.
}
}
}
}
} else {
Log.d("TAG", task.exception!!.message!!) //Never ignore potential errors!
}
}
Now, simply replace collName and docId with the one you have in your database.

RxJava: How to update value of List in onErrorResumeNext

I'm trying to update the validate the list and update the value accordingly but when I'm getting an error, the process gets stopped. I'm calling it in ViewModel class as:
fun validateList(list: List<Model>): Single<List< Model >> {
return Observable.fromIterable(list)
.toFlowable(BackpressureStrategy.LATEST)
.flatMapSingle { validate() }
.toList()
.map { list.mapIndexed { index, testModel ->
(if (it[index] != null) {
testModel.isVerified = it[index].toString()
} else throw Exception("ERROR")); testModel }
}
.onErrorResumeNext { error -> }
And I'm calling it from fragment as:
private fun verify() {
showLoading(true)
testViewModel.validateList(arrayList)
.doFinally {
showLoading(false)
}
.asyncToUiSingle()
.subscribe({
adjustCard(it)
}, {
it.printStackTrace()
})
.addTo(disposables)
}
TestModel:
data class TestModel(
val title: String,
var isVerified: String? = null,
var reason: String? = null )
Please help me to understand how I can update value of reason field in list if one element gets failed status and continue the validations for other elements.
onErrorResumeNext require return an ObservableSource and it will be invoke directly after error happened:
. onErrorResumeNext { error ->
val newList = // Code for new list with updated data
Observable.just(newList) // The new list will be emit to subscriber
}
In your case, I think you can use retry, it will be continue the chain after error happened with given condition, let try:
var index = 0
val validatedList = mutableListOf<Model>()
return Observable.fromIterable(list)
//...
.map {
for (i in index until list.size) {
val testModel = list[i];
if (testModel != null) {
testModel. isVerified = testModel.toString()
validatedList.add(testModel);
} else {
throw Exception("ERROR");
}
}
validatedList
}
.retry { error ->
error.printStackTrace()
index++
index < list.size
}
That's mean when error happened, the retry will trigger and continue the chain if u didn't in the end of list. But, I don't think that's best practice, you maybe try another way. Hope can help you.

Categories

Resources