Using linksRef.on('child_removed', (snapshot) => {..., I'm getting incorrect data being passed to the callback from Firebase..
I have a list of items in my database (simple JavaScript array), and to remove I'm simply grabbing the entire list, filtering out the one that I no longer want, and then pushing that list back to the list property (all within a cloud function).
The child_removed callback within my application is then being called with seemingly a random entry from the list (one that has not been removed), not the item that was removed..
Question 1: Will child_removed work with JavaScript array?
Question 2: If yes, why is Firebase sending through random data?
Related
This is my firebase realtime database structure
I want to retrieve all questions with QID = "PQ1" . What i tried is given below . Its result is null .
database.child("Question").child("QID").equalTo("PQ1").limitToFirst(200).get().addOnSuccessListener {
Log.i("12345", "Got value ${it.value}")
}
My references :
Firebase - Search a child by value
Firebase search by child value
Search firebase by Child of child value
Your call to database.child("Question").child("QID") looks for a child node at path /Question/QID in your database, which doesn't exist and thus explains why you get an empty snapshot.
To query the Firebase Realtime Database needs two steps:
You order all child nodes on a property, on their key, or on their value by calling on of the orderBy... methods.
You then filter the ordered child nodes by calling one or more of the equalTo, startAt, startAfter, endAt, endBefore, limitToFirst and/or limitToLast methods.
While you're doing #2, you're not ordering the nodes first by calling orderBy....
The correct code:
database.child("Question").orderByChild("QID").equalTo("PQ1").limitToFirst(200).get().addOnSuccessListener {
Log.i("12345", "Got value ${it.value}")
}
Also don't forget that executing a query will potentially have multiple results, so the snapshot in it.value contains a list of those results and you will need to iterate over its children. Even if there is only a single result, the snapshot will contain a list of one result.
I have two models, where model A references items in model B. When I delete items from model B, react rerenders before I can update model A to also delete the referenced items.
Example:
I have a feed. The feed is made up of different types of items. Each type of item is stored in its respective model.
The feed order is stored as an array of item IDs, referencing the items in their different substores.
I have made a minimal failing example here. The issue occurs after clicking the button three times
https://codesandbox.io/s/deleting-referenced-items-kmw1e
The key line is
else console.error(">>>> feed order contains deleted item", id);
It's problematic that the feed order might contain deleted items because it could mean there is a programming error that resulted in bad references. In this case it's not a programming error, the second store just hasn't updated yet.
Is there a way I might be able to batch the createAndDeleteTodo, to not evaluate all listeners until the entire thunk and all subthunks have completed?
In the above example it's trivial enough to just have one master action which updates the feed order and the items but it would feel cumbersome if there was more than just one type of item as each item type lives in it's own respective model.
The same thunk action is triggering multiple Actions. And as per the definition of useStoreState:
The useStoreState will execute any time an update to your store's state occurs
So, in effect, when you do this inside the thunk:
actions.setTodos({ newTodos: [newTodo], todoToDelete });
actions.updateFeedOrder({ newTodos: [newTodo], todoToDelete });
there are two actions being dispatched and those would account for a separate store state change event listener. You will get multiple render calls for the multiple store updates.
You have two options:
Either club those actions into one as shown in the example: https://codesandbox.io/s/so-deleting-referenced-items-forked-x4d7v
OR check the useStoreState method for a case on handling the render only when both the store values are matching the count
It seems the problem is that you're dispatching to redux store 2 times. First when you create new items and then when you delete them.
I'd suggest to do it this way:
Create a deep copy of object/array you wanna work with.
Make both operations on that copy.
Dispatch that value to the store.
This way nothing will be rerendered until both operations are finished.
My data is stored in nested form like
Collection->Document->Collection->Document->Collection->Document
I am fetching data using stream builder in flutter.
My aim is to create an instance of a class whose attributes are distributed in all the three layers of collection/documents.
After reading second layer, my function return the class object having partial values null, and shows the error on screen, but after some time it prints the values in the last layer.
I can not use the async/ await functionality here because of the stream builder.
I tried to make the nested function but no again.
I have tried sleep() function as well.
As you can below, After reading productVariant Snapshots, it skips the foreach loop and creates an instance of Order and return. However I'm also printing the values and they got print after the return command execute.
Code Snippet
Thanks for the answers, but I figured out the solution.
I used the nested FutureBuilders which returns promised widgets.
I modified my Order instance by updating variables with widgets.
Before
StreamBuilder -> Fetching Collections and Documents
After
StreamBuilder -> FutureBuilder to Fetch Collection/Document ->FutureBuilder - >To fetch inner Collection/Document
Problem: Whenever I add an order to the orders array, an additional nested array element(-KOPWA...) gets added. I wouldn't mind except, I don't know how to access that nested string to access it's child nodes.
Example of database node for users below:
firebase.database().ref('users/'+userIdState+'/orders/'+<<unique numbervariable>>).push({
"order":{"test":"product","quantity":2}
});
I'm using the above code to push new json objects with a unique number to the firebase array. Still the nested array with the weird strings gets generated.
Can anyone help me understand how to either: create my own nested array with my own unique string or how to access the nested string that gets generated from firebase so I can access it's children nodes.
Multiple instances of nest arrays will be generated by users.
Any help is much appreciated.
Thanks,
Moe
You're experiencing this behaviour because Firebase's push is not the same as an array push. I recommend reading this article to understand how it works.
As for a solution, you can simply change push to set in your code. This will create the structure you were (presumably) expecting, that is
1:
order:
...
This is however potentially unsafe, if you allow concurrent writes (i. e. if the "unique number" in your example is not always unique).
Afaik Firebase recommends using push to safely create collections/"arrays". You can retrieve the generated key by calling the key property on the reference returned by push. Like this:
var ref = firebase.database().ref('users/'+userIdState+'/orders/'+<<unique numbervariable>>).push({
"order":{"test":"product","quantity":2}
});
var generatedKey = ref.key; // the value you're looking for
If you decide to use it, you can probably just drop the order number you have right now and just use the generated one.
From the Transactions doc, second paragraph:
The intention here is for the client to increment the total number of
chat messages sent (ignore for a moment that there are better ways of
implementing this).
What are some standard "better ways" of implementing this?
Specifically, I'm looking at trying to do things like retrieve the most recent 50 records. This requires that I start from the end of the list, so I need a way to determine what the last record is.
The options as I see them:
use a transaction to update a counter each time a record is added, use the counter value with setPriority() for ordering
forEach() the parent and read all records, do my own sorting/filtering at client
write server code to analyze Firebase tables and create indexed lists like "mostRecent Messages" and "totalNumberOfMessages"
Am I missing obvious choices?
To view the last 50 records in a list, simply call "limit()" as shown:
var data = new Firebase(...);
data.limit(50).on(...);
Firebase elements are ordering first by priority, and if priorities match (or none is set), lexigraphically by name. The push() command automatically creates elements that are ordered chronologically, so if you're using push(), then no additional work is needed to use limit().
To count the elements in a list, I would suggest adding a "value" callback and then iterating through the snapshot (or doing the transaction approach we mention). The note in the documentation actually refers to some upcoming features we haven't released yet which will allow you to count elements without loading them first.