Firebase: .priority value - firebase

How do I check the .priority values are in my "Forge"?
According to docs, smaller .priority value comes before larger .priority value. If I use seconds since epoch for priority, and I want the latest children to show up on top, should I set .priority to be 1/seconds?
Children with a number as their priority come next. They are sorted numerically by priority (small to large) and then lexicographically by name (a to z).
From experimentation, I've determined that if I set .priority to java.util.Date#getTime, oldest children show up on top in my Forge, but latest children show up on top in my Javascript on() when ranking using prevChildName. Why is this?

You can see .priority in a json by "Export JSON" from the Forge.

use
snapshot.getPriority();
more at
https://www.firebase.com/docs/javascript/firebase/setwithpriority.html

It's not available from Forge but you can see it from the JSON format:
https://YOURAPP.firebaseio.com/.json?print=pretty&format=export

There's no way in Forge right now to see the actual priority values, but the children will be sorted correctly.
If what you want is to sort items in reverse-chronological-order, I'd suggest simply setting the priority to a normal timestamp (or using push -- it orders them automatically). You can then simply render them backwards to achieve the reverse order you want. For example, rather than appending new messages to the bottom of a list in your app, you could insert them before the first element.

snapshot.exportVal()
Exports the entire contents of the DataSnapshot as a Javascript
object. This is similar to val(), except priority information is
included (if available), making it suitable for backing up your data.
The export format is a Javascript object with ".priority" entries
added to any object with a priority. In the case of primitive values
(a string, number, or boolean) with a priority, the value is wrapped
in an object with ".value" and ".priority" properties. In the case of
primitive values without a priority, a primitive value is returned.
Source: https://www.firebase.com/docs/web/api/datasnapshot/exportval.html

Related

How can I add a conditional field

I would like to have one field appear conditionally based on the value of another. How should I go about achieving this in dexterity?
E.g. One field is a boolean: Is the resource for sale?
If this is set as "yes" I'd like the next field to show up, being an integer- the price of the resource.
If I had to guess, I'd start hacking a javascript solution but I'm assuming there is a technique for doing it in an organised manner, but I can't find anything.
I should also mention that I am doing this to simplify the process of searching through this content later (using eea.facetednav) in which I don't know how to have a boolean search interface return results based on if the integer is > 0.

Firebase reading ordered data reversed order?

I have an ordered list of firebase locations. I'm using a property ut (update time) as their priority. I want to make the list such that it's easy to get the latest updated documents.
So I set the priority to be negative ut.
var query = fb.child('view/documents').limit(20)
query.on('child_added', function(child) {
console.log(child.val())
console.log(child.getPriority())
})
I expect something like this to return the latest 20 documents, but it doesn't, it returns the oldest 20. In the forge I see the listing the way I expect it, the latest documents are on top, but the query is sending me the bottom 20. It seems contrary to my expectations for the query to send me the bottom 20 instead of the top 20.
What really confuses me is that the child_added returns the expected order, latest (smallest priority) first. But again it's the oldest in the list.
Am I doing something wrong or is this a bug in firebase.
Thanks.
I understand your confusion, but that's really how it's supposed to work: limit(20) returns the 20 greatest-priority children, starting with the 20th-greatest-priority child and ending with the absolute-greatest-priority child (and then updating whenever a new child is added whose priority is great enough to make the list).
You can see the example at https://www.firebase.com/docs/queries.html, where the priority is the Unix timestamp of when the message was sent, and messageListRef.limit(100) is used to get the 100 most recent messages (i.e., the 100 greatest-priority messages).
I think what you are looking for is : .startAt()
before the limit(), that will return the data in correct order, without the keyword you will always get the last specified number of children.
Here is the reference : https://www.firebase.com/docs/javascript/query/limit.html

crossfilter filter does not apply on update data. Is it by design?

I am managing a large dateset using crossfilter in my recent project, in which I will need ability to change the data value (a bool). However after the value changed, the filter on this property does not filter out changed item. For instance I have large dataset whose data has a property of Boolean named as 'Ignore'; I create a dimension for this property to filer out the data have ignore= true. In app, user has a capability to change this value from false to true. after value changed true, clear filters and refilter the data on this dimension, I am still getting the data item which supposed being filterred out. Is it by design or there is way to around it?
From the API Docs and source it appears this behaviour is not supported.
https://github.com/square/crossfilter/wiki/API-Reference

dynamodb creating a string set

I have a lot of objects with unique IDs. Every object can have several labels associated to it, like this:
123: ['a', 'hello']
456: ['dsajdaskldjs']
789: (no labels associated yet)
I'm not planning to store all objects in DynamoDB, only these sets of labels. So it would make sense to add labels like that:
find a record with (id = needed_id)
if there is one, and it has a set named label_set, add a label to this set
if there is no record with such id, or the existing record doesn't have an attribute named label_set, create a record and an attribute, and initialize the attribute with a set consisting of the label
if I used sets of numbers, I could use just ADD operation of UPDATE command. This command does exactly what I described. However, this does not work with sets of strings:
If no item matches the specified primary key:
ADD— Creates an item with supplied primary key and number (or set of numbers) for the attribute value. Not valid for a string type.
so I have to use a PUT operation with Expected set to {"label_set":{"Exists":false}}, followed (in case it fails) by an ADD operation. These are two operations, and it kinda sucks (since you pay per operation, the costs of this will be 2 times more than they could be).
This limitations seems really weird to me. Why are something what works with numbers sets would not work with string sets? Maybe I'm doing something wrong.
Using many records like (123, 'a'), (123, 'hello') instead of one record per object with a set is not a solutions: I want to get all the values from the set at once, without any scans.
I use string sets from the Java SDK the way you describe all the time and it works for me. Perhaps it has changed? I basically follow the pattern in this doc:
http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_UpdateItem.html
ADD— Only use the add action for numbers or if the target attribute is
a set (including string sets). ADD does not work if the target
attribute is a single string value or a scalar binary value. The
specified value is added to a numeric value (incrementing or
decrementing the existing numeric value) or added as an additional
value in a string set. If a set of values is specified, the values are
added to the existing set. For example if the original set is [1,2]
and supplied value is [3], then after the add operation the set is
[1,2,3], not [4,5]. An error occurs if an Add action is specified for
a set attribute and the attribute type specified does not match the
existing set type.
If you use ADD for an attribute that does not exist, the attribute and
its values are added to the item.
When your set is empty, it means the attribute isn't present. You can still ADD to it. In fact, a pattern that I've found useful is to simply ADD without even checking for the item. If it doesn't exist, it will create a new item using the specified key and create the attribute set with the value(s) I am adding. If the item exists but the attribute doesn't, it creates the attribute set and adds the value(s). If they both exist, it just adds the value(s).
The only piece that caught me up at first was that the value I had to add was a SS (String set) even if it was only one string value. From DynamoDB's perspective, you are always merging sets, even if the existing set is an empty set (missing) or the new set only contains one value.
IMO, from the way you've described your intent, you would be better off not specifying an existing condition at all. You are having to do two steps because you are enforcing two different situations but you are trying to perform the same action in both. So might as well just blindly add the label and let DynamoDB handle the rest.
Maybe you could: (pseudo code)
try:
add_with_update_item(hash_key=42, "label")
except:
element = new Element(hash_key=42, labels=["label"])
element.save()
With this graceful recovery approach, you need 1 call in the general case, 2 otherwise.
You are unable to use sets to do what you want because Dynamo Db doesn't support empty sets. I would suggest just using a string with a custom schema and building the set from that yourself.
To avoid two operations, you can add a "ConditionExpression" to your item.
For example, add this field/value to your item:
"ConditionExpression": "attribute_not_exists(RecordID) and attribute_not_exists(label_set)"
Source documentation.
Edit: I found a really good guide about how to use the conditional statements

Order of different collection type in java?

Just wanted to confirm the in what order we get the elements from different collection
List
ArrayList:- the sequence in which we put the element we get them in same sequence
LinkedList:- when we add an element in linked list with add(E e) it will be added at last when we get it with itertator it will start from first element to last element. So we can say
the sequence in which we put the element we get them in reverse sequence
Set
HashSet:- No sequence(for getting the elemnets) is guaranted. It will be a random sequence
Tresset:- Will get the elements as per their natural ordering or comparator defined at the time of creation
Map
HashMap:- No sequence(for getting the elemnets) is guaranted. It will be a random sequence
TreeMap:- Will get the elements as per their natural ordering of key or comparator defined at the time of creation
Please let me know if it is correct?
Yup - apart from your use of the word random. The order from a hash set/map won't actually be random; it will just be implementation-specific and unpredicatable. Not quite the same thing - in particular, you shouldn't use it as a source of randomness - but you're right that you shouldn't rely on it being any specific ordering.
This ordering is what you would get if you used an iterator. I think the Java Doc are clear enough for this to be apparent. Mind you this is not all on one page.

Resources