adding elements to firebase realtime database using Trigger - javascript

I am using firebase cloud function to trigger a database update when a field is created on my database.
exports.dbTest2 = functions.database.ref('/{uid}/ignore')
.onCreate((snapshot, context) => {
const uid = context.params.uid
console.log(`Current User ${uid}`)
// Data added at the location
const ignoreData = snapshot.val()
const endTime = new Date(ignoreData.endTime).toString()
// ref matches `/{uid}/ignore`
return snapshot.ref.parent.child('schedule').set({
allDay: false,
endDate: new Date().toString(),
id: 100,
startDate: new Date().toString(),
title: 'test'
})
});
This function gets triggered when I add ignore to my real-time database. When this gets triggered, it looks like below:
However, I want ignore to be an array-like structure that has indices where each index contains the object. Something like this:
I also tried something like return snapshot.ref.parent.child('schedule').child().set(...
but didn't work because child() requires a parameter.
Any help?

You can simply pass an array with objects:
return snapshot.ref.parent.child('schedule').set(
[
{
allDay: false,
endDate: new Date().toString(),
id: 100,
startDate: new Date().toString(),
title: 'test1'
},
{
allDay: false,
endDate: new Date().toString(),
id: 101,
startDate: new Date().toString(),
title: 'test2'
}
]
);
How it looks in my firebase(photos are passed as array):

Related

delete mongoDB item using model after a setTime

I am storing chat app messages in MongoDB. After X time i would like them to delete themselves.
Where in the code do i add the line from the Docs
{expireAfterSeconds: x }
My code for creating the item is
try {
MessageModel.create({
username: user.username,
text: msg,
time: moment().format('h:mm a'),
room: user.room
})
} catch (error) {
// do stuff
}
and my model is set out as below
const MessageSchema = new mongoose.Schema(
{
userName: String,
text: String,
time: String,
room: String
},
{ collection: 'messages' }
)
const messageModel = mongoose.model('MessageSchema', MessageSchema)
Do I add the code to the model? or as a second argument to the create method?
Thanks in advance
The MongoDB TTL collection feature is set by using an index.
First, modify your time-field to store a timestamp as a valid date type. You can use moment().toISOString()
const MessageSchema = new mongoose.Schema(
{
userName: String,
text: String,
time: String,
room: String,
},
{ collection: 'messages' }
)
Set the TTL index like so
db.messages.createIndex( { "time": 1 }, { expireAfterSeconds: 3600 } )
For more information look at the docs

How to update state object key value?

I am declaring dateRangePicker field in component state like below
dateRangePicker: {
selection: {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
},
}
later start date and end date changes as below
let startDate = "2019-04-16";
let endDate = "2019-05-16";
But, I am not able to update these value in state after following code block
this.setState({
dateRangePicker.selection.startDate : startDate,
dateRangePicker.selection.endDate : endDate,
})
I want to update the start and end date accordingly
It doesn't work the way you showed. It should be like this:
this.setState(ps=>({
...ps,
dateRangePicker:{
...ps.dateRangePicker, // Copy old data
selection: {
...ps.dateRangePicker.selection, // Same here
startDate: startDate
endDate: endDate
},
}
}))
We use functional form of setState, because you can see at one point we access data from previous state: ps.selection
what your'e tryin to acheive is to change the state of a deep/nested
object in setState..
const startDT = "new start date"
const endDT = "new end date"
this.setState(prevState => ({
...prevState,
dateRangePicker: {
...prevState.dateRangePicker,
selection: {
...prevState.dateRangePicker.selection,
startDate: prevState.startDate = startDT,
endDate: prevState.endDate = endDT,
}
}})
)
Or,
// copy without reference..
const dateRangePicker = { ...this.state.dateRangePicker }
dateRangePicker.selection = {
startDate: startDT,
endDate: endDT,
}
this.setState({ dateRangePicker })
The state is a immutable object, so you can not modified it, but create a new one, so using spread ... expression to create a new state.

Trying to append/push object to returned array

I have a checkUser function,
module.exports.checkUser = (userData) => {
return new Promise((resolve, reject) => {
iUser.find({ userName: userData.userName })
.exec()
.then((users) => {
Which returns an array of size 1, with one user, accessible through users[0].(...)
To users[0].loginHistory, I need to push the object,
{dateTime: (new Date()).toString(), userAgent: userData.userAgent}
I am using MongoDB, and was wondering if I can do something like,
users[0].loginHistory.push({dateTime: (new Date()).toString(), userAgent: userData.userAgent});
Where userData.userAgent was defined with get('User-Agent);
My schema,
var userSchema = new Schema({
"userName": {
type: String,
unique: true
},
"email": String,
"password": String,
"loginHistory": {
"userAgent": String,
"dateTime": Date
}
});
Clearly the push() JS method isnt working for me. Am I doing something wrong? When checkUser finished processing, after the push(), it expects to replace the document in the MongoDB collection with the updated userHistory,
users[0].loginHistory.push({dateTime: (new Date()).toString(), userAgent: userData.userAgent});
iUser.update({
userName: users[0].userName},
{ $set: { loginHistory: users[0].loginHistory }
})
.exec()
.then(() => {
resolve(users[0]);
})
Any direction would be much appreciated.
If your JSON object is a Date type, it won't have push as a member function. Can you convert userSchema.loginHistory.dateTime to an Array? Then you can work with it like you want (i.e. as a list).
loginHistory is an object in your model but you are pushing into it in your code as if it was an array.
Beside, dateTime field is a date so no need to convert it to a string.
If you need loginHistory to be a collection, change the field to:
"loginHistory": [{
"userAgent": String,
"dateTime": Date
}]
and then use your assignment (no need of toString()):
users[0].loginHistory.push({ dateTime: new Date(), userAgent: userData.userAgent});
If this not what you want, or you can't change the model, you need to change the loginHistory assignment in your code to:
users[0].loginHistory = { dateTime: new Date(), userAgent: userData.userAgent };

Meteor.js & Collection2: Update Method that Inserts New Object in subschema

CONTEXT
I have a collection ("venues"). I'm trying to allow users to add new objects ("rooms" - defined as subschema) to an instance of the venue object. Each room should have an unique id (using autovalue in collection2 schema).
PROBLEM / WHAT I'VE TRIED
I tried two methods:
Venues.insert - attempts to create a new entire Venue instance instead of adding a new row to the roomPricing sub-schema.
Venues.update - using '$set:params" throws an Exception while invoking method 'addRoom' MongoError: Cannot update 'roomPricing' and 'roomPricing.roomId' at the same time. If I remove the Id from the collection, the app updates the 'existing' room values instead of creating a 'new' instance of room.
In summary, I need a method that updates the 'parent' object (the venue) while creating a new 'child' object in the 'room' subschema.
COLLECTIONS
Schema.RoomPricing = new SimpleSchema({
roomId: {
type: String,
autoValue: function(){
return Random.id();
},
optional: true
},
roomName: {
type: String,
max:50,
optional: true
}
}
// MAIN SCHEMA for the Venues colleciton.
Schema.Venues = new SimpleSchema({
venueName: {
type: String,
label: "Venue Name",
max: 200,
optional: false
},
roomPricing: {
type: Schema.RoomPricing,
optional: true
}
}
CONTROLLER & METHOD
var currentVenueId = this.params._id
var params = {
roomPricing: {
roomName: roomName,
sitCapacity: sitCapacity,
}
}
Meteor.call('addRoom', currentVenueId, params);
//Method
Meteor.methods({
'addRoom': function (id, params) {
Venues.insert({
_id: id
},{
$set:params});
}
});
In the end this is what I used - needed $push instead of $set.
'addRoom': function (id, params) {
Venues.update({
_id: id
},{
$push:params});
}

Complex Schema with subdocument

UPDATE:
Currently i have this schema:
var Schema = new schema ({
name: String,
type: { type: String },
date: { type: Date },
descrip: String,
});
But i use this schema for generate 2 documents:
THE A TYPE ({
name: 'A',
type: 'TYPE_B',
date: { type: Date },
descrip: 'DESC_A',
});
THE B TYPE ({
name: 'B',
type: 'TYPE_B',
date: { type: Date },
descrip: 'DESC_B',
});
The name, type and descrip are always the same in the A and B types, the only thing that changes is the date field, so i was thinking, how can i improve this? How can i insert several dates in the same schema, instead of create always an document with the same name, type and descrip values?
So i am trying to create a schema inside other schema, but i dont know if this is possible, it is?
I was trying like this:
var mainSchema = new schema ({
name: String,
type: { type: String },
date: [ dateSchema ],
descrip: String,
});
var dateSchema = new Schema ({
date: {
type: Date
}
});
What i want, is create two mainSchema, type a and type b, and insert dates inside...
Am i doing this right? How can i achieve my goals?
I am searching for a full answer with good explanation, that's why the bounty. I don't accept +/- answers.
To create a record with multiple dates you can use array of Dates.
var mainSchema = new schema ({
name: String,
type: { type: String },
dates: [Date],
descrip: String,
});
The documents will be as follows
THE A TYPE ({
name: 'A',
type: 'TYPE_B',
dates: ["2014-01-22T14:56:59.301Z","2015-01-22T14:56:59.301Z"],
descrip: 'DESC_A',
});
THE B TYPE ({
name: 'B',
type: 'TYPE_B',
dates: ["2015-01-22T14:56:59.301Z","2014-01-22T14:56:59.301Z"],
descrip: 'DESC_B',
});
Reference: http://mongoosejs.com/docs/schematypes.html
For saving the document you can use like.
exports.save = function(req,res){
var test = new newSchema; // new object for newSchema domain.
test.name= req.body.name;
test.type= req.body.type;
test.desc= req.body.desc;
if(req.body.date){
req.body.forEach(function(date){ // For every element of date from client.
test.date.push(date) // This pushes each and every date given from the client into the date array.
})
}
test.save(function (saveErr, saved) { // Saves the new document into db.
if (saveErr) {
console.log(saveErr)
return;
}
res.status(HttpStatus.OK).json(saved);
});
};
For Update you can use like.
exports.update = function(req,res){
newSchema.findOne({name: 'B'},function(err,test){ // Finds a record with name:'B' and stores in test the same can be done for name:'A'.
if(test){
if(req.body.date){
req.body.forEach(function(date){
test.date.push(date) // pushes dates into existing test document (update).
})
}
test.save(function (saveErr, saved) { // Saves (updates) the document.
if (saveErr) {
console.log(saveErr)
return;
}
res.status(HttpStatus.OK).json(saved);
});
}
});
};
Hope this helps.
If your code write down in one section it will look like this
var mainSchema = new schema ({
name: String,
type: { type: String },
date: [ {date: { type: Date } } ],
descrip: String,
});
I think that's wrong. Also you don't need to creat new schema like this, you can use just {} in your code http://www.w3schools.com/js/js_objects.asp . I think correct code must look like this:
var mainSchema = {
name: string,
date: {},
descrip: string
}
And then push into 'date' your dates. Good luck.
======================== HOW TO USE =======================
Sorry for delay. You can use mainSchema.date.date_1 = date; or you can chang date: {}, to date: [], and use mainSchema.date.push(date) depend on your needs.

Categories

Resources