I have the following data structure:
attendance
--- 2020-02-09-PM
--- 2020-02-11-PM
--- 2020-02-16-AM
--- 2020-02-16-PM
--- 2020-02-18-PM
I wanted to get for example the date of 2020-02-16, I would need both PM and AM. So I wanted to query my DB to only get that data.
Here is my attempt:
function getAttendanceCount(orgUid, dates) {
orgUid.forEach(uid => {
dates.forEach(date => {
const getAttendCount = fDB.ref(`organization/${uid}/attendance`)
.orderByChild('attendance')
.startAt(date+'-AM')
.endAt(date+'-PM')
.once('value')
.then(c => console.log(c.val()));
});
})
}
My console.log is null.
Any idea how I could achieve this?
Change this:
const getAttendCount = fDB.ref(`organization/${uid}/attendance`)
.orderByChild('attendance')
Into this:
const getAttendCount = fDB.ref(`organization/${uid}/attendance`)
.orderByKey()
The reason you need to use orderByKey() is because the date are acting as a key and not as a child which would have a value example:
"name" : "peter"
Related
I have a collection in mongodb with a value o type array with 12 rows in it. See the screenshot:
In my code make an axios request in the componentDidMount and successfully get the respone and values
async componentDidMount() {
const {data: locations} = await axios.get('http://localhost:4000/try1');
this.setState({locations})
console.log(locations)
// Use processCsvData helper to convert csv file into kepler.gl structure {fields, rows}
const data = Processors.processCsvData(nycTrips);
console.log(data)
// Create dataset structure
const dataset = {
data,
info: {
// `info` property are optional, adding an `id` associate with this dataset makes it easier
// to replace it later
id: 'my_data'
}
};
// addDataToMap action to inject dataset into kepler.gl instance
this.props.dispatch(addDataToMap({datasets: dataset}));
}
The problem is I am getting the location object like shown in this screenshot:
but my required output is as shown below:
I need the required output to pass it to my mapping application so that the map markers can be generated.
Please advise how I can create an object in the required format.
Following is my simple get api:
app.get('/try1', (req, res) => {
try1.find()
.then(data => res.json(data))
})
Thanks in advance guys.
I'm making a digital Christmas Kalendar for a friend. Every day he can claim a Steam game.
So in mongodb in the user account that I made for him there is a key called codes (object). The structure is as follows:
_id: blbalbalba
codes: {
1 : {
title: GTA V,
code: AISHD-SDAH-HAUd,
claimed_at: ,
},
2 : {
title: Fortnite,
code: HHF7-d88a-88fa,
claimed_at: ,
}
}
Just example data. Now in the client app, when button (door) 7 is pressed/opened I want to insert the current date to the key "claimed_at" in the object with key name "7".
I tried some variations of:
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set: { "codes.`${door_number}`.date_claimed" : date,
}
}
);
But this doesn't work. What did work was: "codes.5.date_claimed". So a static path. In that case the object with name 5 got it's date_claimed key updated.
But how do I use a dynamic path with a variable instead of a number?
Thanks in advance!
If you know the variable value before calling the query i think both of the bellow can work.
var door_number=5;
var date= new Date("...");
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set : { ["codes."+door_number+".date_claimed"] : date}}
);
var door_number=5;
var date= new Date("...");
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set : { [`codes.${door_number}.date_claimed`] : date}}
);
If the dynamic behaviour is based on information on the database, send if you can sample data and expected output, so we know what you need.
I'm trying to update the quantity of a Stripe subscription that has already been created. But I keep getting this error:
"error": {
"message": "Invalid array",
"param": "items",
"type": "invalid_request_error"
}
I am first retrieving the Stripe subscription, updating the value, and then posting the updated value. Here is the code:
const subscription = await stripe.subscriptions.retrieve(
stripe_sub_id
);
subscription.items.data[0].quantity = newCount;
stripe.subscriptions.update(
stripe_sub_id,
{items: { data: subscription.items.data }}
)
What am I doing wrong? How do I update the value of "quantity" within the items.data array?
You can't really just mutate items.data and pass it directly due to the way the Stripe API works(the format of items returned in a retrieve call is not the same as format of the parameters when POSTing, they're different).
So you need to actually write some more custom code/business logic to explicitly create the params object for the change you want. Something like this maybe.
const subscription = await stripe.subscriptions.retrieve(
stripe_sub_id
);
let IdOfPriceToUpdate = "price_xxx";
let newQuantity = 5;
let updatedItemParams = subscription.items.data.
filter(item => item.price != IdOfPriceToUpdate). // find what to change
map(item => {return { id:item.id, quantity:newQuantity}}) // change it
await stripe.subscriptions.update(
stripe_sub_id,
{items: updatedItemParams}
)
https://stripe.com/docs/billing/subscriptions/upgrade-downgrade#changing
question is possibly a duplicate but I haven't found anything that provides an appropriate answer to my issue.
I have an ExpressJS server which is used to provide API requests to retrieve data from a MongoDB database. I am using mongoosejs for the MongoDB connection to query/save data.
I am building a route that will allow me to find all data that matches some user input but I am having trouble when doing the query. I have spent a long while looking online for someone with a similar issue but coming up blank.
I will leave example of the code I have at the minute below.
code for route
// -- return matched data (GET)
router.get('/match', async (req, res) => {
const style_data = req.query.style; // grab url param for style scores ** this comes in as a string **
const character_data = req.query.character; // grab url param for character scores ** this comes in as a string **
// run matcher systems
const style_matches = style_match(style_data);
res.send({
response: 200,
data: style_matches
}); // return data
});
code for the query
// ---(Build the finder)
const fetch_matches_using = async function(body, richness, smoke, sweetness) {
return await WhiskyModel.find({
'attributes.body': body,
'attributes.richness': richness,
'attributes.smoke': smoke,
'attributes.sweetness': sweetness
});
}
// ---(Start match function)---
const style_match = async function (scores_as_string) {
// ---(extract data)---
const body = scores_as_string[0];
const richness = scores_as_string[1];
const smoke = scores_as_string[2];
const sweetness = scores_as_string[3];
const matched = [];
// ---(initialise variables)---
let match_count = matched.length;
let first_run; // -> exact matches
let second_run; // -> +- 1
let third_run; // -> +- 2
let fourth_run; // -> +- 3
// ---(begin db find loop)---
first_run = fetch_matches_using(body, richness, smoke, sweetness).then((result) => {return result});
matched.push(first_run);
// ---(return final data)---
return matched
}
example of db object
{
_id: mongoid,
meta-data: {
pagemd:{some data},
name: whiskyname
age: whiskyage,
price: price
},
attributes: {
body: "3",
richness: "3",
smoke: "0",
sweetness: "3",
some other data ...
}
}
When I hit the route in postman the JSON data looks like:
{
response: 200,
data: {}
}
and when I console.log() out matched from within the style match function after I have pushed the it prints [ Promise(pending) ] which I don't understand.
if I console.log() the result from within the .then() I get an empty array.
I have tried using the populate() method after running the find which does technically work, but instead of only returning data that matches it returns every entry in the collection so I think I am doing something wrong there, but I also don't see why I would need to use the .populate() function to access the nested object.
Am I doing something totally wrong here?
I should also mention that the route and the matching functions are in different files just to try and keep things simple.
Thanks for any answers.
just posting an answer as I seem to have fixed this.
Issue was with my .find() function, needed to pass in the items to search by and then also a call back within the function to return error/data. I'll leave the changed code below.
new function
const fetch_matches_using = async function(body, richness, smoke, sweetness) {
const data = await WhiskyModel.find({
'attributes.body': body,
'attributes.richness': richness,
'attributes.smoke': smoke,
'attributes.sweetness': sweetness
}, (error, data) => { // new ¬
if (error) {
return error;
}
if (data) {
console.log(data)
return data
}
});
return data; //new
}
There is still an issue with sending the found results back to the route but this is a different issue I believe. If its connected I'll edit this answer with the fix for that.
Im using Firebase Firestore and want to update an array field under a userprofile with the latest chat thread's id.. Im guessing that I have to pull the entire array (if it exists) from the chat node under that user, then I need to append the new id (if it doesnt exist) and update the array.. It works when theres only 1 value in the array then it fails after that with the following error:
Transaction failed: { Error: Cannot convert an array value in an array value.
at /user_code/node_modules/firebase-admin/node_modules/grpc/src/node/src/client.js:554:15 code: 3, metadata: Metadata { _internal_repr: {} } }
and here is my firebase cloud function, can anyone tell me where im going wrong ?
exports.updateMessages = functions.firestore.document('messages/{messageId}/conversation/{msgkey}').onCreate( (event) => {
/// console.log('function started');
const messagePayload = event.data.data();
const userA = messagePayload.userA;
const userB = messagePayload.userB;
// console.log("userA " + userA);
// console.log("userB " + userB);
// console.log("messagePayload " + JSON.stringify(messagePayload, null, 2) );
const sfDocRef = admin.firestore().doc(`users/${userB}`);
return admin.firestore().runTransaction( (transaction) => {
return transaction.get(sfDocRef).then( (sfDoc) => {
const array = [];
array.push(...[event.params.messageId, sfDoc.get('chats') ]);
transaction.update(sfDocRef, { chats: array } );
});
}).then( () => {
console.log("Transaction successfully committed!");
}).catch( (error) => {
console.log("Transaction failed: ", error);
});
});
You're nesting arrays in your code here:
const array = [];
array.push(...[event.params.messageId, sfDoc.get('chats') ]);
This leads to an array with two values, the first one being the new messageId and the second value contains an array all of your previous values, e.g.
[ "new message id", ["previous id", "older id"] ]
This type of nested array is something that Firestore (apparently) doesn't allow to be stored.
The solution is simple:
const array = [event.params.messageId, ...sfDoc.get('chats')];
The fact that you have to first load the array to then add a single element to it is one of reasons Firebasers recommend not storing data in arrays. Your current data looks like it'd be better off as a set, as shown in the Firestore documenation:
{
"new message id": true,
"previous id": true,
"older id": true
}
That way adding a chat ID is as simple as:
sfDocRef.update({ "chats."+event.params.messageId, true })
I have looked further into the matter, and I would follow the advice that Frank gave you in his post; allocate the data in collections rather than with arrays as they have greater versatility for Firebase 1. Researching under the examples listed in the Firebase website looking for anything related to a chat, I’ve found the data structure and code for messages that are used by Firechat as they might be of use for you.
In the source code, they use a collection for the their message-id -userId pair with the following topology 2 :
The exact way how the saving is executed at the repository is 3 :
It executes an append of the message into the Room-id collection. Instead of this structure, you could use an userID - messageID pair as it might fit you better.