Firestore - add array of objects - android

I'm having trobule with adding Array of Objects (tables) to Array of objects(restaurants). By that i mean, that I have following Firestore structure:
... (other data)
restaurants: [
0: {
name: name_0
...
tables: [
0: { no_chairs: 5, ... },
]
},
...
]
I know how to add new object to restaurants, but I'm having trouble with adding new restaurant if tables list contains any data.
My code rn:
var collection = firestore.collection('usersData')
.doc(this.currentUser.uid).collection('buisness').doc('restaurants');
collection.update({
'restaurants': FieldValue.arrayUnion([restaurant.toJson()]),
}).then( ... // reaction based on api answer
class Restaurant:
Map<String, dynamic> toJson() => {
'name': name,
...
'tables': tables!=null? [tables] : [], // I think that I should modify this line
};
class Table:
Map<String, dynamic> toJson()=> { // Or this method / use another
'no_chairs': no_chairs,
...
};
Is there any simple way to do it? Preferably without modyfing firestore file structure, but if it is necessary I'm willing to do it.
Extra question:
How to modify object in tables list? For example I want to change no_chairs to 7

From your code above, the line below has a problem:
'tables': tables!=null? [tables] : [],
This part [tables] means you're putting the list tables as an element of the outer list.
To illustrate, if tables was as shown below:
List<int> tables = [1, 2, 3];
Then, [tables] is this:
[[1, 2, 3]]
Solution:
You can just use the tables variable directly since you're sending a list.
Before sending your tables object, you need to convert it to a list of Maps from the list of TableModel that is currently is (according to your comment below).
So you can modify your code to this:
'tables': tables != null ? tables.map((TableModel table) => table.toJson()).toList() : [],
Extra question: How to modify object in tables list? For example I
want to change no_chairs to 7
Solution:
You will have to get the actual list of restaurants and modify the exact table object you want and set the modified list to Firestore.
var collection = firestore.collection('usersData').doc(this.currentUser.uid).collection('buisness').doc('restaurants');
//Get list of restaurants
List<Restaurant> restaurantList = ((await collection.get()).data()).map((dynamic restaurantJson) => Restaurant.fromJson(restaurantJson)).toList();
Set number of chairs
//
restaurantList[restaurantIndex].tables[tableIndex].no_chairs = 7; //This assumes the no_chairs field is not final
//Set list
collection.set({
"restaurants": restaurantList.toJson()
})

Related

List<StudentModel> studentDetails = []; here StudentModel is class in flutter and i don't know how this line of code work

class StudentModel {
final String name;
final String age;
StudentModel({required this.name, required this.age});
}
this is StudentModel class
I didn't understand how the values will store in this List
You can follow the below code to add elements to your list.
List<StudentModel> studentDetails = [];
StudentModel firstStudent = StudentModel(name: "John", age: "16");
StudentModel secondStudent = StudentModel(name: "Doe", age: "17");
studentDetails.add(firstStudent);
studentDetails.add(secondStudent);
studentDetails.forEach((student) {
print(student.name);
});
// Prints:
// John
// Doe
studentDetails is basically a list that contains n number of StudentModel objects. You can visualize it being the following form:
studentDetails = [
StudentModel(name: "John", age: "16"),
StudentModel(name: "Doe", age: "17"),
];
You can use below code snippet for understanding
// Create object to add students
List<StudentModel> students = [];
// Adding student details to list
students.add(StudentModel(name: "Amitabh", age: "65"));
students.add(StudentModel(name: "Akshay", age: "72"));
// Iterate list to see output
students.forEach((student) {
print(student.name);
print(student.age);
});
// Output:
// Amitabh
// 65
// Akshay
// 72
Here we created a object names students for storing a list of students
in next line we are adding student details to list with name and age keys (both keys are required as mention in model)
then we iterate the student list to print student details which we have added.
If you are talking about how this class constructor works then here is some explanation.
In flutter, when you are creating this type of class there are few ways to set value which depends how you created the constructor of data model class.
1. Named parameters
class StudentModel {
final String name;
final String age;
StudentModel({required this.name, required this.age});
}
This type of parameters inside {} is called named parameters. To set these kind of values you need to specify the name of the parameter in which you want to set value like this.
StudentModel _studentModel = StudentModel(name: "John", age: "30");
This will also allows you to setup the required parameters.
If you don't want to use the name each time & simply want to set values then you can second approach.
2. Unnamed parameters
class StudentModel {
final String name;
final String age;
StudentModel(this.name, this.age});
}
Here you can just remove the curly braces. Which allows you to set values like this.
StudentModel _studentModel = StudentModel("John", "30");
3. Optional parameters
In both of above types you have to pass all the parameters because they are required as mentioned in 1st approach & second approach make them required by default.
But if you want to set some parameters as optional in both ways you can do this.
In named you can write like this
StudentModel({required this.name, this.age = 20}); // age must be specified
In unnamed you can try this
StudentModel(this.name, [this.age = 20]); // age must be specified within []
Hope this will help
List studentDetails = [];
The above code is used to initialize "empty" studentDetails list. Also, by declaring this every time you load this widget the list will be initialize as empty.
By add function you can add values to list
Ex. studentDetails.add(StudentModel(name: "Rishabh Gupta", age: "23")));

realm database query to find all objects with a string property contained in a list of strings

using realm for kotlin in android 'io.realm.kotlin:library-base:1.4.0'.
I have the following class:
class MyClazz : RealmObject {
#PrimaryKey
var title: String = ""
var ids: RealmList<Int> = realmListOf()
}
I want to find all objects with a title contained in this list listOf("title1", "title5", "title7")using the Realm Query Language. docs here
I remember it was easy in older versions of realm e.g. using beginGroup and endGroup, but how to do it now with the Realm Query Language ?
If I understand correctly, you want to do an IN query where you want to see if the left hand expression title is in the right hand list "title1", "title5", "title7".
If that's correct, use the IN as shown in the comparison operators. An example
progressMinutes IN { 10, 20, 30, 40, 50, 60 }

Firestore conditional array query

I am trying to get all documents where the length of the "users" array is less than 2 and where the userId is not present already. I am doing the following query, but it is not executing correctly. What is the problem and how can I fix it? I just want all documents where there is only one entry in the array "users" and where the array does NOT contain the current userId.
await FirebaseFirestore.instance
.collection('rooms')
.where("users"[0], isNotEqualTo: userId)
.where('users'[1], isEqualTo: null)
.get()
.then((snapshot) async {
// If no empty room is found, create room
if (snapshot.docs.isEmpty) {
print("No empty room found, creating new room");
roomId = await createRoom(userId);
return roomId;
}
You can't query individual array elements in Firestore. You can only check whether an array contains a specific item.
It sounds like your array items have a specific meaning, in which case you should create (nested) fields that indicate/name the roles. For example:
participants: {
creator: "uid1",
receiver: "uid2"
}
With that you can then query the nested fields with dot notation:
.where("participants.creator", "!=", "uid1")
.where("participants.receiver", "==", null)
Keep in mind there that the participants.receiver field still has to exist in the latter case and have a value of null. Firestore can't filter in fields that don't exist.

Can't convert object of type java.lang.String to type com.thesis.joinerapp.Model.Joins

So i want to query my Firebase Database base on the value that i get from other activity.
private String tripID = "";
tripID = getActivity().getIntent().getStringExtra("tripID");
JoinRef = FirebaseDatabase.getInstance().getReference().child("Join").child(tripID);
FirebaseRecyclerOptions<Joins> options = new FirebaseRecyclerOptions.Builder<Joins>().setQuery(JoinRef,Joins.class).build();
Database Structure:
But it shows an exception
com.google.firebase.database.DatabaseException: Can't convert object
of type java.lang.String to type com.thesis.joinerapp.Model.Joins
While FirebaseUI can perform look ups of data for you, your data has to be in a very specific format for that.
If you want to show a subset of the number of trips, the index has to look like this:
"myTrips": {
"tripID1": true,
"tripID2": true
}
Where tripID1 and tripID2 are the -L keys that you have under /Trip.
You can find another example of this data in the FirebaseUI documentation on showing indexed data.
when you want to use the FirebaseUi, your database structure should be like this.
{
"Join" : {
"tripID" : {
"pushUid" : {
"joinID" : "yourJoinID",
"personCount" : "1",
"tripID" : "yourTrioID",
"uid" : "yourUid"
}
}
}
}
You need to add new root child which is pushId.

Parse Query returns ALL results

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);
}

Categories

Resources