How to organize my model

I am trying to create a simple chat. The user can choose another to talk to him. I am using Ember with firebase. I have built my model as firebase example.

This is my simple model. User Model:

import DS from "ember-data";

var user = DS.Model.extend({
    name : DS.attr('string'),
    messages : DS.hasMany("message", {async : true, inverse : 'owner'})
});

export default user;

      

Message Model:

import DS from "ember-data";

var message = DS.Model.extend({
    date : DS.attr('date'),
    content : DS.attr('string'),
    owner : DS.belongsTo('user', {async : true}),
    target: DS.belongsTo('user', {async : true})
});

export default message;

      

Emberfire does not support searching data types like "findQuery" like ember-data, so how can I get all messages related to a conversation? Is this the correct way to define my model or is there another? Ideally, I just want to get all messages with one request. (from owner to target and from target to owner)

+3


source to share


1 answer


If you are sticking with the official emberfire bindings, you can configure three models:

User:

var user = DS.Model.extend({
    name          : DS.attr('string'),
    conversations : DS.hasMany('conversation', { async: true }),
    convos_users  : DS.hasMany('convo_user', { embedded: true })
});

      

Dialogue:

var conversation = DS.Model.extend({
    messages : DS.hasMany('message', { embedded: true })
});

      

Message:

var message = DS.Model.extend({
    date    : DS.attr('date'),
    content : DS.attr('string'),
    from    : DS.belongsTo('user', { async : true })
});

      

Then set up the built-in convos_users index:



var convos_users = DS.Model.extend({
    with         : DS.belongsTo('user', {async : true}),
    conversation : DS.belongsTo('conversation', { async: true })
});

      

So the resulting schema looks something like this in firebase:

{
  'users': {
    'user_1': {
      'name': 'Terrance',
      'conversations': {
        'convo_1': true
      },
      'convo_users': {
        0: {
          'with': 'user_2',
          'conversation': 'convo_1'
        },
        ...
      }
    },
    'user_2': {
      'name': 'Phillip',
      'conversations': {
        'convo_1': true
      },
      'convo_users': {
        0: {
          'with': 'user_1',
          'conversation': 'convo_1'
        },
        ...
      }
    },
    ...
  },

  'conversations': {
    'convo_1': {
      'messages': {
        0: {
          'date': 123456789,
          'content': 'Hey buddy!',
          'from': 'user_1'
        },
        1: {
          'date': 123456789,
          'content': 'Hey guy!',
          'from': 'user_2'
        },
        ...
      }
    }
  }
}

      

This setting allows you to merge messages into a general message flow, so you only receive messages for the conversation you want to view. The 'from' attribute on the message allows you to display the user they came from and sort the alignment of the chat box or whatever you are looking for.

Finally, indexing both the list of conversations the user has ever had, and the index of another user ID in the conversation and that conversation ID. This way, when user A posts a message to user B, you can perform the findBy computation in the user_conversations index. If there is a match, open the conversation with the found Conversation ID and add the messages to the conversation's embedded messages array:

actions: {
  sendMessage: function(msg) {
    var userX = this.current_user.get('convos_users').findBy('with','user_X');

    // No User
    if (!userX) {
      // 1. Create a new Conversation (var myRoom)
      // 2. Save room id to users
      // 3. Save room to your conversations model list
    }

    // Else
    myRoom.messages.pushObject(msg);
    myRoom.save();
  }
}

      

}

Good luck!

+4


source







All Articles