Firebase how to query between two keys - firebase

I have a list with the following data:
(List of halls, every hall has some events that start at a given time and end at a different time)
{
name: "hall 1"
events: [
{
name: "React lecture",
startAt: 1500225422,
endAt: 1500226422
}
]
}, {
name: "hall 2"
events: [
{
name: "Angular lecture",
startAt: 1500227422,
endAt: 1500228422
}
]
}
I would like to query all of the events, and their halls, to see what event is currently happens and where.
Given a current timestamp (lets say 1500225556), I would like to get:
{
name: "hall 1"
events: [
{
name: "React lecture",
startAt: 1500225422,
endAt: 1500226422
}
]
}
If necessary, I can flatten this a bit, and have a list of halls, and a list of events with a reference to the hall they take place at.
SQL equivalent (list):
WHERE startAt < 1500225556 AND endAt > 1500225556
I cannot think of a solution without a custom cloud function.

Related

Azure CosmosDB User Defined Function returns records equal to the total number of records in the table

I am just no understanding how user defined functions in CosmosDB works.
Why is the my UDF in Cosmos DB returning results equal to the number of records in the table?
My table has 4 records currently.
Here are the records -
{
"users": [
{
"partitionKey": "user",
"userPhoneNumber": "14168000000",
"userDisplayName": "Test User 1"
},
{
"partitionKey": "user",
"userPhoneNumber": "18055678978",
"userDisplayName": "Test User 2"
},
{
"partitionKey": "user",
"userPhoneNumber": "17202228799",
"userDisplayName": "Test User 3"
},
{
"partitionKey": "user",
"userPhoneNumber": "17780265987",
"userDisplayName": "Test User 4"
}
]
}
Here is my UDF -
function findUserByPhoneNumber(users, contactNumbers){
var result;
for (let i = 0; i < contactNumbers.length; i++) {
if (contactNumbers[i] == "14168000000") {
result = contactNumbers[i];
}
return result;
}
Here is my SQL -
SELECT udf.findUserByPhoneNumber(c,["14168000000","17200000000"]) FROM c
And here is the result I am getting -
[
{
"$1": "14168000000"
},
{
"$1": "14168000000"
},
{
"$1": "14168000000"
},
{
"$1": "14168000000"
}
]
I am only expecting one record to be returned.
The SELECT statement in your query will never help you filter items in your query. If you want to filter you should use WHERE in your query. While you could use a UDF in a WHERE statement that returns e.g. a boolean you should typically avoid it as the database can not use it indexes to efficiently retrieve your data and will have to use your UDF on every document to calculate if it should be retrieved.
For your scenario the query could be:
SELECT *
FROM c
WHERE ARRAY_CONTAINS(['14168000000', '17200000000'], c.userPhoneNumber)
The reason your UDF always returns 14168000000 is because you always use the array ['14168000000', '17200000000'] as input in your UDF and check if any of those values equals 14168000000 and return that.

Normalized ngrx entities id reference

I am trying to normalise my API data with normalizr.
Basically my RESTful API provides a /items resource with all CRUD operations and a /items/:item-id/pictures sub resource with CRUD operations as well.
GET /items returns something a deep nested response that needs normalization:
[
{
id: "item-id-1",
name: "Item One",
pictures: [
{
id: "picture-id-1",
mimeType: "image/png"
},
{
id: "picture-id-2",
mimeType: "image/jpeg"
}
]
},
{
id: "item-id-1",
name: "Item One",
pictures: []
}
]
Now for my question: Should I normalise the code with a reference of all picture ID on the item entity or a reference to the item on the picture entity?
Reference on the item:
{
items: {
"item-id-1": {
id: "item-id-1",
name: "Item One",
pictures: ["picture-id-1", "picture-id-2"]
}
...
},
pictures: {
"picture-id-1": {
id: "picture-id-1",
mimeType: "image/png"
},
"picture-id-2": {
id: "picture-id-2",
mimeType: "image/jpeg"
}
...
}
}
vs. reference on the picture:
{
items: {
"item-id-1": {
id: "item-id-1",
name: "Item One",
}
...
},
pictures: {
"picture-id-1": {
id: "picture-id-1",
itemId: "item-id-1"
mimeType: "image/png",
},
"picture-id-2": {
id: "picture-id-2",
itemId: "item-id-1"
mimeType: "image/jpeg"
}
...
}
}
My application will provide actions to delete and add single pictures to an item. With the reference on the item I feel like it is much more expensive if I just delete an image with DELETE /items/:item-id/pictures/:picture-id. Then I need to have an item reducer function that loops through every pictures array in the item store and update the state there as well as in the pictures store. But all the examples for redux and normalizr use this approach
The reference on the picture I think is much more straight forward but I do not know how to achieve that result with normalizr. (I could write it myself pretty easily tho)

Observable contains array of ID to call another observable

I have a data structure in firebase
{
"name": "Sample",
"category": ["123456", "789012"]
}
The array of category contains ID which refers to documents in another collection. I can get the above document as Observable. What I really what as the end result is the below data structure
{
"name": "Sample"
"category": [
{
"name": "Category 1"
},
{
"name": "Category 2"
}
]
}
How can I bring this data? I don't think switchMap works for this. If so, can someone give an example of that?
You can try using flatMap and forkJoin. FlatMap allows you to chain multiple async requests together and forkJoin allows you to wait for all observables to return a value before continuing.
And you could wright something like this:
var finalData;
firstRequest('sample').flatMap((data) => {
// assuming data = { name: "Sample", catagory: [ "23123", "31321", ... ] }
finalData = data;
var observables = [];
data.catagory.forEach((c) => {
observable.push(secondRequest(c));
});
return forkJoin(observables);
}).flatMap((results) => {
// assuming results is an array like [ { name: "Catagory 1", ... } ]
finalData.category = results;
return finalData;
});

Get list of related values Angularfire 4 Ionic 3

I am working to calculate the difference between two times in ionic.
I am using AngularFire and my tree looks like this:
{
"users": {
"name": {
"17": {
"10": {
"2017": {
"-Kwfm1k9_A74PzlmijUJ": {
"date": "17/10/2017",
"hora": "17:20:58",
"status": "In"
},
"-Kwfm8wEJ8Oob4YFvNNu": {
"date": "17/10/2017",
"hora": "17:21:27",
"status": "Out"
},
"-KwfoKkPJMt2g8AQNmxq": {
"date": "17/10/2017",
"hora": "17:31:00",
"status": "In"
},
"-Kwfp0BOAGnM-2_MfziP": {
"date": "17/10/2017",
"hora": "17:33:58",
"status": "Out"
},
"-KwfqW5XKpUNedda4rZz": {
"date": "17/10/2017",
"hora": "17:40:31",
"status": "In"
},
"-Kwg0pQDlI3FMV3BPNaa": {
"date": "17/10/2017",
"hora": "18:29:58",
"status": "Out"
}
}
}
}
}
}
}
I would like to get a difference between the first and second, third and fourth, fifth and sixth, remembering that they are related by the tag "Status".
First In - Out = difference
Second In - Out = difference
Third In - Out = difference
Always doing the difference between the In's and Out's.
In's are for when a person come in the room. Out's are for when a person come out of the room. I want to record the time a person spend inside of a room.
So the results would be:
"17:20:58" - "17:21:27" = 00:01:29
"17:31:00" - "17:33:58" = 00:02:58
"17:40:31" - "18:29:58" = 00:49:27
Do you have any tip on refactoring this code so it works fine?
Remembering I'm using Ionic 3 with AngularFire4
Appreciate the help.
To achieve your goal I recommend you to restructure your data. For now, there is no real relation between the IN's and OUT's.
A possible approach would be to create some node which wraps the checkIn and the checkOut. Let's call it session. Each time a user checks in a new session get's created and each time a user checks out a session get's closed.
Your structure could look similar to this:
"sessions": {
"uid": { // or name or whatever
"17-10-2017": { // not sure if you need the date in the structure, but if you need it make a single node like this
"-Kwfm1k9_A74PzlmijUJ": { // this is a session create it on each check in
"checkin": 1508354574, // timestamp
"checkout": 1508354584
},
}
}
}
Here's a code example (just to give you an idea how it could look like):
var ref = firebase.database().ref("sessions/uid"); // uid must be dynamic
// checkin
ref.push({
checkin: firebase.database.ServerValue.TIMESTAMP // make sure to use the servers timestamp
}); // creates a new session with a pushkey as id
// checkout
ref.child('sessionId').update({
checkout: firebase.database.ServerValue.TIMESTAMP
});
// stats
ref.child('sessionId').once('value', function(snap) {
var session = snap.val();
var difference = session.checkout - session.checkin;
// now you have the difference in milliseconds or seconds depending on your timestamp format. this can be formatted whatever unit you want e.g. minutes, hours...
});
Hope this gives you an idea, how it could be done.

Is it possible to change Firebase path from an object?

I'm trying to make a very simple thing, something like:
root: {
objects: {
id_subobj1: { // these are two objects doing current events.
name: "subName1",
description: "it's nice"
},
id_subobj2: {
name: "subName2",
description: "it's cool"
}
},
history: {
// once they are done, I'd like to store them in this branch as an exact copy as they were in the "Objects" branch.
id_subobj: {
name: "name",
description: "it was nice"
}
}
}
What I want to achieve is to get my objects, and something like copy and paste them into the history branch.
I'm trying to do so, but I had no success of doing that.
Any ideas?

Resources