FIrebase setData kef-value sequence not preserved - firebase

I am trying to add data in firebase as the key-value sequence I have provided in setData.
create({Function onAdded, Function onDuplicate}) async {
bool temp = await lrCheck();
if (temp) {
await fireStore.collection("Admin").document(TextFieldData.lrNO).setData(
{
"lrNO": TextFieldData.lrNO,
"departureDate": TextFieldData.departureDate,
"partyName": TextFieldData.partyName,
"vehicleNo": TextFieldData.vehicleNo,
"origin": TextFieldData.origin,
"destination": TextFieldData.destination,
"quantity": TextFieldData.quantity,
"invoiceNo": TextFieldData.invoiceValue,
"invoiceValue": TextFieldData.invoiceValue,
"arrivalDate": TextFieldData.arrivalDate,
"materialType": TextFieldData.materialType,
"phoneNo": TextFieldData.phoneNo,
},
).whenComplete(onAdded());
But the data stored in firebase is in alphabatical orer of keys plzz help.
ex:
arrivalDate: value
destination: value
and so on ....

Fierstore does not set an order for the fields in a document. If you need an order, you will have to apply that in your app code. If you have an array of ordered data to store, consider putting that data in a single list type field instead.

The data in the firebase document are stored in key-value pairs so, There should be no problem even if the data is received in unordered fashion as long as you are mapping the data correctly in your model.

Related

pushing multiple values to the same database location without overwriting existing data

How do I append new values to an array in realtime database, for example appending new images urls to an array.
"1":{
"title":"some title",
"imgs": [
"https://img1",
"https://img2",
"https://img3",
"https://img4"
]
}
the push() methods adds unique keys which I dont want.
This does overwrite all the data in the imgs array:
set(ref(db, postId +'/imgs'), {
document.getElementById('input_img_url').value,
})

Flutter Firebase firestore append data with unique ID

I'm working on the Flutter app where users can save multiple addresses. Previously I used a real-time database and it was easier for me to push data in any child with a unique Id but for some reason, I changed to Firestore and the same thing want to achieve with firestore. So, I generated UUID to create unique ID to append to user_address
This is how I want
and user_address looks like this
And this is how it's getting saved in firestore
So my question Is how I append data with unique id do I have to create a collection inside users field or the above is possible?
Below is my code I tried to set and update even user FieldValue.arrayUnion(userServiceAddress) but not getting the desired result
var uuid = Uuid();
var fireStoreUserRef =
await FirebaseFirestore.instance.collection('users').doc(id);
Map locationMap = {
'latitude': myPosition.latitude,
'longitude': myPosition.longitude,
};
var userServiceAddress = <String, dynamic>{
uuid.v4(): {
'complete_address': completedAddressController.text,
'floor_option': floorController.text,
'how_to_reach': howtoreachController.text,
'location_type': locationTag,
'saved_date': DateTime.now().toString(),
'user_geo_location': locationMap,
'placeId': addressId
}
};
await fireStoreUserRef.update({'user_address': userServiceAddress});
If I use set and update then whole data is replaced with new value it's not appending, so creating a collection is the only solution here and If I create a collection then is there any issue I'll face?
You won't have any issues per se by storing addresses in a separate collection with a one-to-many relationship, but depending on your usage, you may see much higher read/write requests with this approach. This can make exceeding your budget far more likely.
Fortunately, Firestore allows updating fields in nested objects via dot notation. Try this:
var userServiceAddress = {
'complete_address': completedAddressController.text,
'floor_option': floorController.text,
'how_to_reach': howtoreachController.text,
'location_type': locationTag,
'saved_date': DateTime.now().toString(),
'user_geo_location': locationMap,
'placeId': addressId
};
await fireStoreUserRef.update({'user_address.${uuid.v4()}': userServiceAddress});

Object Mapping in Flutter to Realtime DB Firebase

I want to save my List with Objects in Firebase Realtime DB. The Problem is, that when I save my objects there, they dont have an auto generated key, their key is 0, 1, 2,... :
I am mapping my Poll object this way:
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'allowBarChart': allowBarChart,
'allowPieChart': allowPieChart,
'description': description,
'custom-questions': customQuestions != null
? List<dynamic>.from(customQuestions.map((x) => x.toJson()))
: [],
'choice-questions': choiceQuestions != null
? List<dynamic>.from(choiceQuestions.map((x) => x.toJson()))
: [],
};
My Question is: how to do it, so the key of each value is not 0,1,2,3,... It should be auto generated from firebase, for example: 1fdDfasLPO3g. I hope you know what I mean.
Thanks in advance!
When the Firebase SDK encounters a List it is mapped to a JSON array, which is stored with sequential numeric indices, as seen in the screenshot you shared. There is no way to change this mapping.
If you want to store items with Firebase's push keys (which start with -M at the moment), you should generate those in your application code (by calling push()), and store the questions in a Map<string, dynamic>.

How to update only part of the JSON?

I have a DynamoDB table:
+--------------------------------------------------+
| Customer ID (Primary Key)|Gamestats (JSON entry) |
+--------------------------------------------------+
JSON:
{
"Gamestats": [
{
"ID": "QuickShootingMode",
"status": 1
},
{
"ID": "FastReloadMode", // Just want to update this and not update the entire JSON
"status": 0
}
],
"CustomerID": "xyz"
}
I want to update only parts of the JSON. What is the best way to do it? Eg, update the QuickShootingMode to be false.
One way is to make a call and fetch the JSON and then Iterate the JSON and update the value and then put the new JSON back in dynamo DB. It means it would make 2 calls
A) to get the data and
B) to put the data in DB.
Is there a better way by which I could directly update the data and avoid making these extra network calls? I could convert each key of the JSON to be a column in dynamo BD, but if the number of keys grows then I’ll end up having lots of column (which might be a bad design), hence I think having the JSON saved in one column Game stats would make more sense.
Map<String, AttributeValue> key = new HashMap<>();
AmazonDynamoDB dynamoDB = dynamoDBClient.getDynamoDB();
key.put(USER_ID_KEY, new AttributeValue().withS("xyz"));
key.put("Gamedata", new AttributeValue().withS("some JSON"));
PutItemRequest request = new PutItemRequest()
.withTableName(table)
.withItem(key);
PutItemResult result = dynamoDB.putItem(request);
Is there a better way to achieve what I want?
It looks like from your question you are storing stringified JSON. If so an update won't help you, but as far as I can tell there is no value in storing stringified JSON instead of using dynamodb maps and lists.
You can use an update to set a nested attribute in a map or a list. Using a map instead of a list for the gamestats attribute is better because then you don't have to worry about the order of the attributes.
Javascript example with Gamestats being a map.
dynamodb.update({
TableName: table,
Key: key,
UpdateExpression: 'SET #gs.#qs.#status = :newStatus',
ExpressionAttributeNames: {'#gs': 'Gamestats', '#qs': 'QuickShootingMode', '#status': 'status' },
ExpressionAttributeValues: { ':newStatus': false }
}, callback)

Search by key, order by value

Here is a sample of my Firebase data:
I need to be able to search userFavorites for a given user (here, afaapy...) and return the results ordered by the values (timestamps) to get all the user's favorites in order of the date added to the database.
I can search by key as follows, and retrieve all favorites for the given user:
databaseRef.child("userFavorites").queryOrderedByKey().queryEqual(toValue: user.uid).observe(...)
But these favorties are ordered by their keys. If I try to order by value as follows, I get "Cannot use multiple queryOrderedBy calls!":
databaseRef.child("userFavorites").queryOrderedByKey().queryEqual(toValue: user.uid).queryOrderedByValue().observe(...)
How can I retrieve the favorites for a given user sorted by their value?
Second question: is there an easier way to retrieve data in the order it was added to the database?
You can't order the same ref multiple times as documented here
When you use a order or a filter method, it returns a Query Interface. See it as a filtered reference containing only a subset of the original data. It means that
databaseRef.child("userFavorites").orderByKey().equalTo(user.uid)
will not return userFavorite/${user.uid} but userFavorite filtered to show only the user.uid entry. You can see it by doing
databaseRef.child("userFavorites").orderByKey().equalTo(user.uid).ref.key
That should return 'userFavorites'
In your case, I see two options:
Keep going with orderByKey().equalTo() and sort the results yourself
Or use directly child() to get the user, then sort via Firebase (and don't forget to use the Firebase's snapshot.forEach to be sure you get the data in the query order):
databaseRef.child(`userFavorites/${user.uid}`).orderByValue().once('value', (snapshot) => {
if (snapshot.exists()) {
snapshot.forEach((child) => {
console.log(`${child.key}: ${child.val()}`)
})
}
})

Resources