Firebase Sorting Data Retrieval - javascript

This is the code that I have: I am trying to get data stored in the Firebase Database sorted by wage. The order of the database goes: "Posts -> PostID(.push when saving) -> Wage." I have the data retrieval working just not in order.
var PostsRef = firebase.database().ref().child("Posts");
PostsRef.on('child_added', function(data) {
var title = data.val().title;
var description = data.val().description;
var completionDate = data.val().completionDate;
var complexity = data.val().complexity;
var wage = data.val().wage;
var uid = data.val().userID;
});

You're storing the wages as string, which means that they will be sorted in lexicographical order:
1
13
2
20
3
If you want to get the results in numerical order, you should store the wages as numbers, so without the quotes.
If you store them from your code, this might require that you convert it with parseInt(wagesAsString).
After you store the wages as numbers, you can get them in order with:
var PostsRef = firebase.database().ref().child("Posts");
var query = PostsRef.orderByChild("wage");
query.on('child_added', function(data) {

Related

Incorrect Range Height - Google Apps Scripts

I am currently trying to get grab values from another spreadsheet and then paste it into a destination spreadsheet. The problem I am running into is that I am getting incorrect range height and incorrect range widths when I run this code. I read something about 2d arrays but I believe I already have a 2d array here to paste to the spreadsheet. Thank you for your time.
function GmailToDrive_StaticTest(gmailSubject, importFileID){
var threads = GmailApp.search('subject:' + gmailSubject + ' -label:uploaded has:attachment'); // performs Gmail query for email threads
for (var i in threads){
var messages = threads[i].getMessages(); // finds all messages of threads returned by the query
for (var j in messages){
var attachments = messages[j].getAttachments(); // finds all attachments of found messages
var timestamp = messages[j].getDate(); // receives timestamp of each found message
var timestampMinusOne = new Date(timestamp.getTime() - (86400000)); // sets the received timestamp to exactly one day prior (# in milliseconds)
var date = Utilities.formatDate(timestampMinusOne, "MST", "yyyy-MM-dd"); // cleans the timestamp string
for (var k in attachments){
var blobs = {
dataType: attachments[k].getContentType(), // retrives the file types of the attachments
data: attachments[k].copyBlob(), // creates blob files for every attachment
fileName: attachments[k].getName()
};
var tempFile = DriveApp.createFile(blobs.data.setContentType('text/csv')).setName(blobs.fileName.split("-", 1).toString() + date); // creates csv files in drive's root per blob file
var tempFileConverted = Drive.Files.copy( {}, tempFile.getId(), {convert: true} ); // converts created files to gsheets
var importData = {
file: tempFileConverted,
ID: tempFileConverted.getId(),
Sheet1: SpreadsheetApp.openById(tempFileConverted.getId() ).getActiveSheet(),
Sheet1_Values: SpreadsheetApp.openById(tempFileConverted.getId() ).getActiveSheet().getDataRange().getValues()
};
tempFile.setTrashed(true);
var importData_Sheet1_Rows = importData.Sheet1.getMaxRows(); - 2;
var importData_Sheet1_Columns = importData.Sheet1.getMaxColumns(); - 2;
var destSheet = SpreadsheetApp.openById(importFileID).getSheets()[0];
destSheet.clearContents();
Logger.log(importData.Sheet1_Values)
destSheet.getRange(1, 1, importData_Sheet1_Rows, importData_Sheet1_Columns).setValues(importData.Sheet1_Values);
DriveApp.getFileById(importData.ID).setTrashed(true);
}
}
}
}
getMaxRows() and getMaxColumns() return the maximum number of column and rows in a sheet, while getDataRange().getValues() return all the values in a sheet that contain data .
So, unless all the cells in a sheet have data the dimensions won't match !
The best you could do is to get the actual size of the data array and use that to set the range for the values in the destination sheet.
It goes (more) simply like this :
destSheet.getRange(1, 1, importData.Sheet1_Values.length, importData.Sheet1_Values[0].length).setValues(importData.Sheet1_Values);
you don't need the other values for rows and columns, just ignore that in your script.

Sorting data in Firebase with JavaScript, how to compare all register in an array of objects?

I found this method, with which I have ordered the hours what I store in my records, I wanted them to be sorted from highest to lowest, but when I test the code, I notice that only two values of the array are compared, which are the first registers.
I've seen other methods of comparison and the logic is the same, what am I doing wrong? I group the messages per user, using the id of the user as key of the array , then I save the rest of data. I do this for retrieve the current messages, since I want show a list of the last currently messages sent.
This is the code:
var ref = new Firebase('https://chatfbexample.firebaseio.com/all-messages');
ref.on("value", function (snapshot) {
var Messages = [];
var value = 0;
snapshot.forEach(function (snap) {
value = snap.val().id;
fecha = snap.val().id;
Messages[value] = [];
Messages[value]['fecha'] = snap.val().fechahora; //I receive a date with the format HH:MM:SS
Messages[value]['texto'] = snap.val().texto;
});
function compare(a, b) {
var time1 = a['fecha'].replace(/:/gi, '1');
var time2 = b['fecha'].replace(/:/gi, '1');
var data1 = parseInt(time1);
var data2 = parseInt(time2);
// alert(time1);
if (data1 > data2)
return -1;
if (data1 < data2)
return 1;
return 0;
}
Messages.sort(compare);
for (var i in Messages) {
console.log("Hour: " + Messages[i]['fecha'] + ' ' + ' Message: ' + Messages[i]['texto']);
}
});
the result is something like this
Hour: 12:11:13 Message: whats'up?
Hour: 11:38:44 Message: p
Hour: 11:49:01 Message: hey?
the second and the third messages are not being compared
an image of my Firebase database
First off it probably would be better for you to save a timestamp from Firebase instead of an actual time, which was probably created on the client side, inside your database. This way you could easily let Firebase handle the sorting.
You would need to use firebase.database.ServerValue.TIMESTAMP to save the exact time at which Firebase received your message inside fechahora.
Following you could simply query all of your messages ordered by their child fechahora.
ref.orderByChild("fechahora").on("value", function (snapshot) {
//Do stuff with your already sorted data
}
If you want your query to have a better performance set the .indexOn property of your node containing all the messages inside your Firebase Database rules to fechahora.
Bonus: If you want your data to be ordered newest to oldest instead of oldest to newest, you just need to use the negative value of the timestamp created by Firebase.
Instead of ordering client-side, you'll be better off asking the server to sort the messages:
ref.orderByChild("fechahora").on(...
Make sure that you define the proper index in your Firebase security rules:
{
"rules": {
"all-messages": {
".indexOn": "fechahora"
}
}
}
Without that the sorting will still work, but will happen on the client instead of the server.

How to convert Json arrays to integer from string in Java script

In my application I will get a Json string from server (java).
When I retrieve the Json in Java script what I get is
var data = [{"value":"3","label":"17 hr"}
{"value":"2","label":"18 hr"},
{"value":"1","label":"19 hr"}]
}]
What I want is
var data = [{"value":3,"label":"17 hr"},
{"value":2,"label":"18 hr"},
{"value":1,"label":"19 hr"}]
}]
That is value column is retrieved as strings instead of integer values. How to retrieve them as integers? What is the best or optimal way to do the same?
var data = [{"value":"3","label":"17 hr"},
{"value":"2","label":"18 hr"},
{"value":"1","label":"19 hr"}]
// if you want to keep the data var untouched
var parsedData = data.map(function(item) {
// make sure you don't change item's reference by returning new object
return {
value: parseInt(item.value, 10),// you will end up with NaN if item.value is not a number
label: item.label
};
});
// if you don't care about mutation
data.forEach(function(item) {
item.value = parseInt(item.value, 10)
});

Firebase - Data structure issue for extracting an object from nested structure

Firebase - Data structure issue for extracting an object from nested structure.
I want to find the uid and then check if the key is a jobId.
I've labelled accordingly below.
I'm using typescript and angular2 with firebase.
This is my current attempt that returns "null":
var jobId = "-K5fIAiuHM-4xeEQJiIS";
var uid = "3f61ae7a-99a1-4cbf-9c8e-00b2249956a7";
var userRef = this.refApp.child('key').child(uid);
var query = userRef.child('jobId').child(jobId);
query.on('value', (snap) => {
//This returns null
var response = snap.val();
});
This is my database structure:
Your structure is /applications/$userId/$jobId. Use those keys to get to your data.
JSBin Demo
var jobId = "-K5fIAiuHM-4xeEQJiIS";
var uid = "3f61ae7a-99a1-4cbf-9c8e-00b2249956a7";
var refApp = new Firebase('<my-firebase-app>/applications');
var jobRef = refApp.child(uid).child(jobId);
jobRef.on('value', (snap) => console.log(snap.val()));
Right now you're using "key", which I believe is from my previous demo. That's just for show, not for your actual solution. Keep your data structure in mind when reading the sample code, because it can vary.

Parse Multiple doesNotMatchKeyInQuery

I am having a problem using Parse queries in javascript. I want to try and use multiple doesNotMatchKeyInQuery functions but it only allows the last one to be used. Any ideas how I can make code like this work? Ignore the errors that might exist in other parts of the code. I wrote this as an example
//Query 1
var Class1 = Parse.Object.extend("Class1");
var class1Query = new Parse.Query(Class1);
class1Query.equalTo("id", id1);
//Query 2
var Class2 = Parse.Object.extend("Class2");
var class2Query = new Parse.Query(Class2);
class2Query.equalTo("id", id2);
//Query 3
var Class3 = Parse.Object.extend("Class3");
var class3Query = new Parse.Query(Class3);
class3Query.equalTo("id", id3);
//Bringing it all together
var finalQuery = new Parse.Query("User");
//This is the part below I am talking about
finalQuery.doesNotMatchKeyInQuery("objectId", "id1", class1Query);
finalQuery.doesNotMatchKeyInQuery("objectId", "id2", class2Query);
finalQuery.doesNotMatchKeyInQuery("objectId", "id3", class3Query);
finalQuery.find({
success: function (results) {
response.success(results);
},
error: function (error) {
response.error(error);
}
});
It's not possible to do such a complex query in a single request. However, you can fetch the keys you don't want to match ahead of time, and construct a secondary query from that.
I've written up an example based upon your code above:
// Assuming we're actually dealing with 3 different classes,
// and these can't be combined into a single query
var class1Query = new Parse.Query('Class1');
class1Query.equalTo('id', id1);
var class2Query = new Parse.Query('Class2');
class2Query.equalTo('id', id2);
var class3Query = new Parse.Query('Class3');
class3Query.equalTo('id', id3);
// Fetch the results from all three queries simultaneously
Parse.Promise.when([
class1Query.find(),
class2Query.find(),
class3Query.find()
]).then(function(results) {
// results will contain three arrays of results
// We can now build a query where the objectId is not equal
// to any of the objectIds of the results
var ids = [];
results.forEach(function(set) {
set.forEach(function(obj) {
ids.push(obj.id);
});
});
return new Parse.Query('FinalClass').notContainedIn('objectId', ids).find();
})
I want to caution you that this query will not be efficient for large sets of data. "Does not equal" queries are never fast, because they have to loop over every object in the table. If there is another way to get your data, I highly encourage it.

Categories

Resources