Firebase orderByChild without repeated data - javascript

I'm trying to sort and display firebase data however I'm stuck. My database looks like this :
I need to sort the data by nr_of_matches and I can do that by querying like this :
const ref = firebase.database().ref('Matches/'+db_name).orderByChild('nr_of_matches')
ref.once('value', function (snapshot) {
snapshot.forEach(function (childSnapshot) {
const matches = childSnapshot.val().matches
const nr_of_matches = childSnapshot.val().nr_of_matches
const the_matched = childSnapshot.val().the_matched
console.log("matches : "+matches)
});
});
However, I retrieve repeated data doing it like this.
To not get repeated data I can do it like this:
const ref = firebase.database().ref('Matches/'+db_name+"/"+child.key).orderByChild('nr_of_matches')
ref.on('value', function (snapshot) {
const matches = snapshot.val().matches
const nr_of_matches = snapshot.val().nr_of_matches
const the_matched = snapshot.val().the_matched
console.log("matches : "+matches)
});
but then it's not sorted anymore. Any idea how do sort this out?

If you dont want to retrieve repeated data, then you can use a query:
const ref = firebase.database().ref('Matches/'+db_name+"/").orderByChild('nr_of_matches').equalto(2);
ref.on('value', function (snapshot) {
const matches = snapshot.val().matches
const nr_of_matches = snapshot.val().nr_of_matches
const the_matched = snapshot.val().the_matched
console.log("matches : "+matches)
});

Related

Execute promise or await with generated string variable

I am building a mongoose query and storing it in a variable call query. The code below shows it
let query = "Product.find(match)";
if (requestObject.query.sortBy) {
query = query.concat(".", "sort(sort)");
const parts = requestObject.query.sortBy.split(":");
sort[parts[0]] = parts[1] === "desc" ? -1 : 1;
}
if (requestObject.query.fields) {
query = query.concat(".", "select(fields)");
const fields = requestObject.query.fields.split(",").join(" ");
const items = await Product.find(match).sort(sort).select(fields); //.populate("category").exec();
/**const items = await Product.find(match).sort(sort).select("-__v"); //.populate("category").exec();**/
}
I am facing an issue when attempting to run a mongoose query that I have generated and stored in a string. When I run it in post man, the response is 200 but no data is returned. Below is a console.log(query) on line 2
what I hope to achieve is to have await or create a new promise execute the content id query variable like shown below
const items = new Promise((resolve) => resolve(query)); //.populate("category").exec();
items
? responseObject.status(200).json(items)
: responseObject
.status(400)
.json({ message: "Could not find products, please try again" });
I will appreciate it very much that and also if you can give me a better way of doing it, I will love that
This doesn't really make sense. You are building a string, not a query. You can't do anything with that string. (You could eval it, but you really shouldn't). Instead, build a query object!
let query = Product.find(match);
if (requestObject.query.sortBy) {
const [field, dir] = requestObject.query.sortBy.split(":");
const sort = {};
sort[field] = dir === "desc" ? -1 : 1;
query = query.sort(sort);
}
if (requestObject.query.fields) {
const fields = requestObject.query.fields.split(",");
query = query.select(fields);
}
//query.populate("category")
const items = await query.exec();
if (items) {
responseObject.status(200).json(items)
} else {
responseObject.status(400).json({ message: "Could not find products, please try again" });
}
If you really want to get that string for something (e.g. debugging), build it separately from the query:
let query = Product.find(match);
let queryStr = 'Product.find(match)';
if (requestObject.query.sortBy) {
const [field, dir] = requestObject.query.sortBy.split(":");
const sort = {[field]: dir === "desc" ? -1 : 1};
query = query.sort(sort);
queryStr += `.sort(${JSON.stringify(sort)})`;
}
if (requestObject.query.fields) {
const fields = requestObject.query.fields.split(",");
query = query.select(fields);
queryStr += `.select(${JSON.stringify(fields)})`;
}
//query.populate("category")
//queryStr += `.populate("category")`;
console.log(queryStr);
const items = await query.exec();
…

How to push a new object to an array if not already in localStorage

I am trying to implement a simple 'add to favorites' feature but can't quite get things working in local storage.
I am able to push an object/array to local storage and retrieve it back but when I click on the next item to 'add to favorites' I end up overwriting the previous one rather than adding a new object to the array.
code below:
const push1 = async (movieId, movieName, image) => {
const stringId = JSON.stringify(movieId);
const stringName = JSON.stringify(movieName);
const stringImage = JSON.stringify(image);
// our array
let moviesList = [];
// our object
let movies = {
movieId: stringId,
movieName: stringName,
image: stringImage
};
moviesList.push(movies);
// storing our array as a string
localStorage.setItem("movieList", JSON.stringify(moviesList));
let updatedMoviesList = [];
const retrievedMovies = localStorage.getItem("movieList");
const parseRetrievedMovies = JSON.parse(retrievedMovies);
console.log("retrievedMovies: ", retrievedMovies);
console.log("parseRetrievedMovies: ", parseRetrievedMovies);
parseRetrievedMovies.push(movies);
};
How can I update the array if the same object is not already there?
Probably you can use Set() instead which helps you store unique movies in localStorage.
Try as the following:
const stringId = '12';
const stringName = 'Name';
const stringImage = '<img-url>';
const moviesList = new Set();
const movie = {
movieId: stringId,
movieName: stringName,
image: stringImage
};
moviesList.add(JSON.stringify(movie));
console.log('first attempt', JSON.parse(Array.from(moviesList)));
moviesList.add(JSON.stringify(movie));
console.log('second attempt', JSON.parse(Array.from(moviesList)));
I hope this helps!
Check if object is alreadyin retreived movies using array.some and only if not present push it.
const retrievedMovies = localStorage.getItem("movieList");
if(retrievedMovies) {
const parseRetrievedMovies = JSON.parse(retrievedMovies);
console.log("retrievedMovies: ", retrievedMovies);
console.log("parseRetrievedMovies: ", parseRetrievedMovies);
const movieExists = parseRetrievedMovies.some((m) => movies.movieId === m.movieId ))
if(!movieExists) {
parseRetrievedMovies.push(movies);
}
}
Your function isn't reading the old setting. Instead you're starting with a new, empty array:
let moviesList = [];
Here you could instead load the data saved last time, like this:
let moviesList = localStorage.getItem("movieList");
Then modify it by adding the new movie, then save, as you are already doing.
Hope this helps.

Retrieving the first element from data snapshot

I'm trying to pull out the first record from the code below.
exports.sendBuyerNotification = functions.database.ref('/Bids/{uid}').onWrite((async(change,context)=>{
const bid= change.after.val();
const prodid = bid.prodID;
const new_price = bid.price;
const biddata= admin.database().ref('/Bids');
biddata.orderByChild('prodID').equalTo(prodid).limitToLast(2).once('value',function(snapshot){
var old_data = [];
old_data.push(snapshot.val());
var mystring = JSON.parse(snapshot.val())
return console.log("Old price" + mystring[0].price);
Result : undefined
Looks like you probably will get back an array of up to 2 items from the database because of limitToLast(2). But you need to check if you're actually getting data back from the database before anything else - see the console.log statements below - I have made some other suggestions also.
Try this and see if it solves you issue:
exports.sendBuyerNotification = functions.database.ref('/Bids/{uid}').onWrite((async(change,context) => {
const bid = change.after.val();
console.log(bid) // are you getting a value from this?
const prodid = bid.prodID;
const new_price = bid.price;
const biddata= admin.database().ref('/Bids');
biddata.orderByChild('prodID')
.equalTo(prodid)
.limitToLast(2)
.once('value', function(snapshot){
console.log(snapshot.val()) // check you are getting a value?
const myString = snapshot.val();
console.log("Old price" + myString[0].price);
return {
message: "Old price $" + myString[0].price,
values: snapshot.val()
};
})
})

forEach with single document firebase queries in client side?

I have different document id for every loop and when I query inside the forEach loop query is working but not pushing the obj into the array
function getAllDonations() {
donations = [];
const user_session_data = sessionStorage.getItem('LoginInfo');
const parse_user_login_data = JSON.parse(user_session_data);
let TABLE_NAME = "donation_favourites";
let get_requests_qry = App.db.collection(TABLE_NAME);
get_requests_qry.where('user_id', '==', parse_user_login_data.user_id).get().then(snapshot => {
let changes = snapshot.docChanges();
changes.forEach(change => {
var one_item = change.doc.data();
let TABLE_NAME1 = "donation_requests";
let get_requests_qry1 = App.db.collection(TABLE_NAME1);
get_requests_qry1.doc(one_item.donationId).get().then(snapshot => {
donations.push(snapshot.data())
});
});
console.log("checking the data",donations.length) //this length is not coming
});
}
If you want to read the files in use forloop but it is not recommended for large loop for small loop it is ok
if you want to read files parallel use forEach
You can also do it with async and await instead forLoop
await Promise.all(changes.map(async (change) => {
var one_item = change.doc.data()
let TABLE_NAME1 = "donation_requests";
let get_requests_qry1 = App.db.collection(TABLE_NAME1);
var snapshot1 = await get_requests_qry1.doc(one_item.donationId).get()
donations.push(snapshot1.data())
}));

How to traverse through the auto key generated by firebase push() in React Native?

I have created a search that queries the discogs api for Albums. when I swipe the Album it gets pushed into the realtime database. Firebase auto generates keys for each item pushed which is great, but I am not sure how to handle these keys. How do I get the image url into my require statement? I
here's the function that pushes to the database.
saveToCollection() {
const myFirebaseRef = firebase.database().ref();
myFirebaseRef.push({
albums: `${this.props.album.cover}`
});
}
Any help would be greatly appreciated!
Update with code from comments:
componentWillMount() {
const rootRef = firebase.database().ref();
const albumRef = rootRef.child('albums');
albumRef.once('value', (snapshot) => {
snapshot.forEach((childSnapshot) => {
var childKey = childSnapshot.key;
var childData = childSnapshot.val(); // ... this.setState({albums: childKey.childData}) }); }); }// This is just a sample script. Paste your real code (javascript or HTML) here.
if ('this_is' == /an_example/) {
of_beautifier();
} else {
var a = b ? (c % d) : e[f];
}
You could iterate over the firebase auto generated keys using for...in and push each value in into an array then use the Mustache {{#.}} ... {{/.}} tag pair to iterate over each object in the array.
let arr = [];
for(let autoKey in childData){
arr.push(childData[autoKey]);
}
let tpl = '{{#.}} {{albums}} {{/.}}';
Mustache.render(tpl, arr);

Categories

Resources