Parse Query returns ALL results - android

I'm writing a Xamarin Android app which is using Parse.com as the backend. I'm running a query against a Parse Class called Beacons, of which one of the columns is a Pointer to another class called BeaconCat.
I'm therefore using two queries as shown below, but when it returns the data, it lists ALL of the categories within the BeaconCat class, not just the one which matches the initial query.
I'm expecting just one category, not all 13 of them. Any idea why?
// First query on class 1.
var innerQuery = ParseObject.GetQuery("Beacons");
innerQuery.WhereEqualTo("minor", minor);
// Query on class 2 which passes in first query.
var newQuery = ParseObject.GetQuery("BeaconCat");
newQuery.WhereMatchesQuery("Category", innerQuery);
IEnumerable<ParseObject> Myresults = await newQuery.FindAsync();
foreach (var result in Myresults)
{
var category = result.Get<string>("Category");
Console.WriteLine ("Category " + category);
}

Related

Firestore query StartAt(DocumentReference) not giving proper result

In my firestore database,there are 12+ documents.I am getting the first 3 documents correctly by calling the below function on button click. But on the secondclick, though the documentReference is passed correctly, its not retrieving any data.The querySnapshot size is coming 0. What could be the problem.
Given below is the declaration
private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
private val colRef: CollectionReference = db.collection("Notebook")
private var lastResult: DocumentReference? = null
private lateinit var query: Query
and below is the onButtonClick code :
private fun loadNoteNew() {
#Suppress("SENSELESS_COMPARISON", "LiftReturnOrAssignment")
if (lastResult == null) {
query = colRef.orderBy("priority")
.limit(3)
} else {
Log.i(TAG, "Start ${lastResult!!.id}")
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
}
Log.i(TAG, "before get")
query.get()
.addOnSuccessListener { querySnapshot ->
var data = ""
Log.i(TAG, "querySnapshot Size : ${querySnapshot.size()}")
if (lastResult != null) {
Log.i(TAG, "querySnapshot ID : ${lastResult!!.id}")
}
for (snapshot in querySnapshot) {
val note = snapshot.toObject(Note::class.java)
note.id = snapshot.id
val title = note.title
val desc = note.description
val priority = note.priority
data += "${note.id} \nTitle =$title \nDescription = $desc\nPriority : $priority\n\n"
}
if (querySnapshot.size() > 0) {
data += "---------------\n\n"
textView_loadData.append(data)
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference
Log.i(TAG, lastResult!!.id)
}
}
}
Given below is the logcat for first click
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 3
I/FireStoreExample: P9hIw4Ai7w4IHP6H3ew3
and given below is the logcat of second click
I/FireStoreExample: Start P9hIw4Ai7w4IHP6H3ew3
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 0
I/FireStoreExample: querySnapshot ID : P9hIw4Ai7w4IHP6H3ew3
Please help me find out,where i am getting it wrong.
Thanks
The second query result is empty because of a misunderstanding on the semantics of query pagination using startAt and startAfter methods.
Let's say the Notebook collection contains N documents. When you make the first query you're asking for the first 3 documents ordered by the priority field so the query is returning documents 1..3. Then upon the second click you're expecting the query to return the next 3 results so indeed you're expecting documents 4..6. The keypoint here is that both startAt and startAfter paginate based on the value of the ordered field rather than with the last document retrieved. Overall the semantics of startAt and startAfter are roughly as follows.
orderby(X).startAt(Y) => Return documents whose X field is greater than or equal Y
orderby(X).startAfter(Y) => Return documents whose X field is strictly greater than Y
With that in mind, let's examine what the code is actually doing when you make the second query:
// At the end of the first query...
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference
// Second query
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
In the code above you're asking for the documents whose "priority" field is greater than document reference "P9hIw4Ai7w4IHP6H3ew3" and indeed there are no documents greater than that, therefore the result set is empty. Here is api reference for both.
There is yet another thing to note. Because these methods filter upon the fields value the position of the cursor could be ambiguous. For instance, if you have 4 documents with priority 3 and already retrieved the leading three if you set startAfter(3) you'll be missing a document. Similarly, if startAt(3) were to be made you'll get back the same three documents. This is also pointed out in the documentation. All in all you have a couple of options to make this work as intended:
Add another orderby in another field so that documents are uniquely identified by the combination so to prevent any cursor ambiguity and be able to use startAfter with guarantees. Next snippet build upon the doc samples and your code.
// first query
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.limit(3)
// Save last document
lastResult = querySnapshot.documents[querySnapshot.size() - 1]
// Second and next queries
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.startAfter(lastResult)
.limit(3)
Lastly remember that it might be simpler to just query all the documents if they're not many and delay optimizations until they become a performance issue.

Realm Simple Retrieve query returns null?

I have one table(Test) in the database,it contains the id(primary key),name,status,checkid.
I am written the simple query to get the record based on the checkid.but sometimes query returns null in android with kotlin.
below is the sample table fields
id = "1",name = "raj",status=0 and checkid="12345" and this is my query
val selTest = realm.where<Test>().equalTo("checkid", "12345").findFirst()
result always retuns null
Below are the realm db details
Instance Address : incredible-soft-bike.us1a.cloud.realm.io

Unable to fetch the list column of AWS DynamoDB in Android Kotlin

I am developing an Android application using Kotlin and AWS DynamoDB. I am new to both technologies. What I am doing now is I am trying to scan data from a table of DynamoDB. I know how to scan it. But the problem is that one of the column has List data type.
I have a table called item with the following columns.
Note in particular the Images field.
In Kotlin Android, I scan the table like this.
val dynamoDBClient = AmazonDynamoDBClient(AWSMobileClient.getInstance().credentialsProvider)
val fetchedItems: ArrayList<Any> = ArrayList();
val scanRequest = ScanRequest().withTableName(MainApplication.DB_TABLE_ITEMS);
scanRequest.exclusiveStartKey = lastEvaluatedKey
val scanResult = dynamoDBClient.scan(scanRequest)
scanResult.items.forEach { item ->
Log.i("ITEM_NAME", item.get("Name")?.s)
val viewItem = ItemDO()
viewItem.id = item.get("Id")?.s
viewItem.description = item.get("Description")?.s
viewItem.name = item.get("Name")?.s
viewItem.userId = item.get("UserId")?.s
viewItem.images = item.get("Images")?.ns
fetchedItems.add(viewItem)
Log.i("IMAGES_COUNT", item.get("Images")?.ns?.size.toString())
}
But this
item.get("Images")?.ns
always return null even if the data exists in the column as in the screenshot below.
Why my code is not fetching the list data type but others?
The code looks good and should be returning data for all the attributes irrespective of their type. I have equivalent piece of code in java that works as expected. Can you try inspecting the value returned by item.get("Images") before making the null-safe call. Type of the value returned by item.get("Images") is AttributeValue and so there is a possibility that the value gets lost in the course of implicit type conversion.

How to check if record exists or not using Anko?

I am learning to fetching data from sqlite using anko. I can print the data successfully (if the record exist) but my application always crash when the data doesn't exist.
the error says:
parseSingle accepts only cursors with a single entry
I know exactly the meaning of error, I just dont know how to solve it.
here is the code for query:
fun getUserByUid(uid: Int): UserModel
{
val data = context.database.use {
val db = context.database.readableDatabase
val columns = UserModel.COLUMN_ID + "," + UserModel.COLUMN_NAME + "," + UserModel.COLUMN_API_KEY
val query = db.select(UserModel.TABLE_NAME, columns)
.whereArgs("(uid = {userId})",
"userId" to uid)
query.exec {
val rowParser = classParser<UserModel>()
parseSingle(rowParser) // this line that trigger error exception
}
}
return data
}
I tried to find count function in query or rowParser variable to check if the record exist or not but could not find it.
From the wiki page.
https://github.com/Kotlin/anko/wiki/Anko-SQLite#parsing-query-results
Parsing query results
So we have some Cursor, and how can we parse it into regular classes? Anko provides functions parseSingle, parseOpt and parseList to do it much more easily.
Method Description
parseSingle(rowParser): T Parse exactly one row
parseOpt(rowParser): T? Parse zero or one row
parseList(rowParser): List Parse zero or more rows
Note that parseSingle() and parseOpt() will throw an exception if the received Cursor contains more than one row.

What is the Android equivalent of this iOS parse statement , userQuery.includeKey("favoriteHouses.landlord" ?)

I am converting an iOS app to Android. The app is using Parse as backend.
I have stuck at this particular line (nested pointer, if I am correct) :
userQuery.includeKey("favoriteHouses.landlord")
Now I do not know how to convert this to Android :
parseQuery.include("favoriteHouses.landlord");
The above conversion does not yield any results.
Actually, I am able to get the array of pointers. But I also want to retrieve the rows of user table which exists in a field called landlord in another table.
Here is the case :I have two tables: One is "House" and other is "User" . A user can mark houses favorite. So the favorite marked houses are stored as array of pointers in the user table.These pointers point to the houses in the house table. In the house table, there is pointer type field called landlord which contains the object id of user and is of pointer type. So, while fetching those fav houses I also want the user's by using that landlord pointer which points back to the user table.
And the whole code that I am translating to android is :
// A query which will return the internal array of the object received by the objectQuery
class PFArrayQuery: PFQuery {
var objectQuery: PFQuery
var returnsKey: String
init(className: String, objectQuery: PFQuery, returnsKey: String) {
self.objectQuery = objectQuery
self.returnsKey = returnsKey
super.init(className: className)
}
override func findObjectsInBackgroundWithBlock(block: PFQueryArrayResultBlock?) {
objectQuery.getFirstObjectInBackgroundWithBlock { (result: PFObject?, error: NSError?) in
if let error = error {
block?(nil, error)
} else if let array = result?[self.returnsKey] as? [PFObject] {
block?(array, nil)
} else {
block?([], nil)
}
}
}
}
Now the above class is used like this :
override func queryForTable() -> PFQuery {
let emptyQuery = PFQuery()
guard let user = User.currentUser(),
userQuery = User.query() else {
return emptyQuery
}
let query = PFArrayQuery(className: "House", objectQuery: userQuery,
returnsKey: "favoriteHouses")
userQuery.includeKey("favoriteHouses")
// this is the line which I am unable to translate.
**userQuery.includeKey("favoriteHouses.landlord")**
userQuery.whereKey("objectId", equalTo: user.objectId ?? "")
return query
}
And now my translated code is :
ParseQuery parseQuery = ParseQuery.getQuery("House");
parseQuery.include("favoriteHouses");
parseQuery.include("favoriteHouses.landlord");
parseQuery.whereEqualTo("objectId",ParseUser.getCurrentUser().getObjectId());
I have also explained my situation here on this page :
Please correct me.
Thanks

Categories

Resources