简体   繁体   中英

How do I set a created_on field on the server in a new Meteor Collection document?

I'm building a chat room that displays posts in chronological order. I'm currently setting the time of the user's post in the client js on the submit event of the "entry" template:

Template.entry.events =  {
  'submit': function(e){
    e.preventDefault();
    //console.log(this.userId());
    var user = Meteor.user();
    var roomName = Session.get('currentRoomName');
    Messages.insert({
      user: user,
      room_name: roomName,
      message: $('#message').val(),
      created_on: new Date().getTime()
    });
    $("#message").val('');
  }
};

My issue is that because this date is set on the client, if a user changes the time on their machine, it will be recorded as such allowing the user to post ahead of or behind the current conversation. Ideally, I'd be able to update the created_on time on the server after receiving a new chat entry to reflect the current UTC time on the server and correct whatever value comes in. I'd still want to have the time on the client for latency compensation, etc.

I've read through a lot of the Meteor documentation on II have a suspicions that I might be solve this using .observe(), but I'm new to both Meteor and Mongodb. Would it be crazy to observe every document in the entry collection? Is it possible to only observe new entries?

I'm also using the auth branch - not sure if that will make any difference.

If there were a lot of users in a chat room, this non-question might end up being related.

Apologies if this is something super easy in Mongo/Meteor that I'm just missing.

The easiest solution is to use a method rather than the implicit one created by Messages.insert .

On the server:

Meteor.methods({
  addMessage: function(room_name, message) {
    Messages.insert({
      userId: this.userId,
      room_name: room_name,
      message: message,
      created_on: new Date().getTime();
    });
  });
});

On the client:

Template.entry.events =  {
  'submit': function(e) {
    e.preventDefault();
    Meteor.call('addMessage', Session.get('currentRoomName'), $('#message').val());
  }
}

This will create a record immediately on the client (with the client's date), simultaneously creating a record on the server (with the server's date), and it'll then overwrite the client's record when it next syncs.

I strongly suggest you the ACL introduced in auth branch. You can do some validations and/or modifications when insert/update/remove/fetch. Take a look at the Meteor.Collection.prototype.allow under the source file packages/mongo-livedata/collection.js .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM