Update object child without id in Firebase function - firebase

Hope you can help me.
In a trigger of firebase database function I'm trying to update the
object of a child without knowing the id.
So, I want to update the categoria elements by only knowing the of it, but without knowing the product one.
Please help...

You may first retrieve the categoria data. Assuming you know the first key (LNBxRLsPR0OY8-_Cnm) and you have one categoria item only (if more than one categoria will explain with another code snap)
firebase.database().ref('product/' + key + '/categoria').once('value', snapshot=>{
if (snapshot.exists()) var categoriaKey = Object.keys(snapshot.val()[0])
firebase.database().ref('product/' + key + '/' + categoriaKey).set(newCategoriaObject)
})
EDIT:
productList={}
firebase.database().ref('product').once('value', snap=>{
snap.forEach(p=>{
productList[p.key]=p.val().name;
})
})
with above product list object array. Scenario: You will need to show the list of products names to the user. Upon the user selected a product, then you may retrieve the key with below function.
function findKey(productList, selectedProductName) {
for (let key in productList)
if (productList[key] === selectedProductName) return key;
}
key = findKey(productList, selectedProductName);
So, with the above simple codes, you will get product key, selected by the user. If you don't have another scenario:)

Related

Flutter getting a specific field from firebase and assigning it to list

I am trying to query data from firestore and assign it to a List.
My users collection is as follows
List<String> emailList = ['Select email', 'email1', 'email2'];
I am trying to populate the above emaillist with the emails of persons such that the list is populated by emails of the persons where the groupId is equal to groupId of current user.
I tried querying by Firebase.instance.collection.where but it gets an error saying it cant be assigned to a List.
Any idea on how to do that?
It sounds like the issue is how you are adding to the list. You have to loop through the snapshot query and for each document, add to the list.
Firestore.instance.collection('users').getDocuments().then((snapshot) => {
snapshot.documents.forEach((doc) {
emailList.add(doc.data['email']);
})
});
Hope this helps!

Flutter: How to remove a specific array data in firebase

I'm having a problem right now in firebase. Where I try to delete/remove a specific array data. What is the best way to do it? Ps. I'm just new in firebase/flutter.
My database structure:
Data that i'm trying to remove in my database structure(Highlighted one):
First create a blank list and add element in the list which you want to remove then Update using below method
Note : For this method you need the documennt id of element you want to delete
var val=[]; //blank list for add elements which you want to delete
val.add('$addDeletedElements');
Firestore.instance.collection("INTERESTED").document('documentID').updateData({
"Interested Request":FieldValue.arrayRemove(val) })
Update:
Much has changed in the API, although the concept is the same.
var collection = FirebaseFirestore.instance.collection('collection');
collection
.doc('document_id')
.update(
{
'your_field': FieldValue.arrayRemove(elementsToDelete),
}
);
Firestore does not provide a direct way to delete an array item by index. What you will have to do in this case is read the document, modify the array in memory in the client, then update the new contents of the field back to the document. You can do this in a transaction if you want to make the update atomic.
This will help you to add and remove specific array data in could_firestore.
getPickUpEquipment(EquipmentEntity equipment) async{
final equipmentCollection = fireStore.collection("equipments").doc(equipment.equipmentId);
final docSnap=await equipmentCollection.get();
List queue=docSnap.get('queue');
if (queue.contains(equipment.uid)==true){
equipmentCollection.update({
"queue":FieldValue.arrayRemove([equipment.uid])
});
}else{
equipmentCollection.update({
"queue":FieldValue.arrayUnion([equipment.uid])
});
}
}
Example

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()}`)
})
}
})

Firebase,iOS: Appending key-value pair into a child node

I have the following User Table structure in Firebase
As you can see in the user that I have opened, I have a Posts section, inside this post section holds the Id's all articles which have been posted by this user.
The issue I am facing is as follows:
When the user creates a new article it's saved within the Posts Table, after the save I return the newly generated ID which I then pass on to the user table, I trying to insert the newly created ID into the post section of the user, so I assumed the URL would be something like this:
Users/{UserId}/Posts
However all this does it create a new section called posts, it doesn't actually insert the record into the given area.
My code which isn't working is as follows:
let linkPost = [childautoID: true]
FIRDatabase.database().reference().child("Users/\(UserId)/Posts").child(UserId).setValue(linkPost)
FYI the two id's that are currently inside Posts I added manually.
I've also tried the following:
FIRDatabase.database().reference().child("Users/\(UserId)/Posts").setValue(linkPost)
However all this does it remove all existing Id's and then inserts the new id.
I prefer something like this. This automatically append the data without fetching first
FIRDatabase.database().reference().child("Users/\(UserId)/Posts").child(UserId).setValue(true)
To append a key-value pair in Firebase Database child node use this :-
Make a Firebase Database Reference to the Posts node of that currentUser FIRDatabase.database().reference().child("Users").child(FIRAuth.auth()!.currentUser!.uid).child("Posts")
Check if Posts node exists in your user's DB, If not then create one by :- parentRef.setValue([postId : "True"]) in else block.
But if Posts node does exist retrieve it as a NSMutableDictionary , set the new object to it, and then store the updated Dictionary to that node.
func storePostsToDB(postID :String!, userID : String! = FIRAuth.auth()!.currentUser!.uid){
let parentRef = FIRDatabase.database().reference().child("Users").child(userID).child("Posts")
parentRef.observeSingleEventOfType(.Value, withBlock: {(friendsList) in
if friendsList.exists(){
if let listDict = friendsList.value as? NSMutableDictionary{
listDict.setObject("True", forKey: postID)
parentRef.setValue(listDict)
}
}else{
parentRef.setValue([postID : "True"])
}
})
}
Calling the function:-
storePostsToDB("yourPostID")// If you want to store in the currentUser DB
storePostsToDB("yourPostID", userID : otherUserID)//If you want to store the post in some other users database with uid `otherUserID`

Pagination in DynamoDB

I have a requirement for to show the search result on the jsp with maxcount of 10 and it should have a pagination to traverse back and forward as pagination functionality.
Dynamodb has a lastevaluatedkey, but it doesn't help to go back to the previous page, though I can move to the next result set by the lastevaluatedKey.
Can anybody please help on this.
I am using Java SPRING and DynamoDB as the stack.
Thanks
Satya
To enable forward/backward, all you need is to keep
the first key, which is hash key + sort key of the first record of the previously returned page (null if you are about to query the first page).
and
the last key of the retrieved page, which is hash key + sort key of the last record of the previously returned page
Then to navigate forward or backward, you need to pass in below parameters in the query request:
Forward: last key as the ExclusiveStartKey, order = ascend
Backward: first key as the ExclusiveStartKey, order = descend
I have achieved this in a project in 2016. DynamoDB might provide some similar convenient APIs now, but I'm not sure as I haven't checked DynamoDB for a long time.
Building on Ray's answer, here's what I did. sortId is the sort key.
// query a page of items and create prev and next cursor
// cursor idea from this article: https://hackernoon.com/guys-were-doing-pagination-wrong-f6c18a91b232
async function queryCursor( cursor) {
const cursor1 = JSON.parse(JSON.stringify(cursor));
const pageResult = await queryPage( cursor1.params, cursor1.pageItems);
const result = {
Items: pageResult.Items,
Count: pageResult.Count
};
if ( cursor.params.ScanIndexForward) {
if (pageResult.LastEvaluatedKey) {
result.nextCursor = JSON.parse(JSON.stringify(cursor));
result.nextCursor.params.ExclusiveStartKey = pageResult.LastEvaluatedKey;
}
if ( cursor.params.ExclusiveStartKey) {
result.prevCursor = JSON.parse(JSON.stringify(cursor));
result.prevCursor.params.ScanIndexForward = !cursor.params.ScanIndexForward;
result.prevCursor.params.ExclusiveStartKey.sortId = pageResult.Items[0].sortId;
}
} else {
if (pageResult.LastEvaluatedKey) {
result.prevCursor = JSON.parse(JSON.stringify(cursor));
result.prevCursor.params.ExclusiveStartKey = pageResult.LastEvaluatedKey;
}
if ( cursor.params.ExclusiveStartKey) {
result.nextCursor = JSON.parse(JSON.stringify(cursor));
result.nextCursor.params.ScanIndexForward = !cursor.params.ScanIndexForward;
result.nextCursor.params.ExclusiveStartKey.sortId = pageResult.Items[0].sortId;
}
}
return result;
}
You will have to keep a record of the previous key in a session var, query string, or something similar you can access later, then execute the query using that key when you want to go backwards. Dynamo does not keep track of that for you.
For a simple stateless forward and reverse navigation with dynamodb check out my answer to a similar question: https://stackoverflow.com/a/64179187/93451.
In summary it returns the reverse navigation history in each response, allowing the user to explicitly move forward or back until either end.
GET /accounts -> first page
GET /accounts?next=A3r0ijKJ8 -> next page
GET /accounts?prev=R4tY69kUI -> previous page

Resources