ember.jsfirebaseember-datafirebase-realtime-databaseemberfire

Ember database new record event and observer


My web app is built using Ember.JS and Firebase for storing data. It also serves as a backend for a mobile app. Users can use mobile app to send a 'help-request' - the app manipulates directly with the Firebase records. When the change is made admin of the web app can see the notification on the screen. That works fine. Now I want to add a sound to this notification.

My general idea to solve it to add an observer that will be triggered when a new record of help-request type is added to the database.

I found a post sort of explaining how to do it but it's using deprecated methods like ArrayControler.

I added a simple observer to help-request model that is triggered when property/ies of the record are modified. That works fine but seems to be a hack rather than a real solution.

So the big question is: 1. Is there any callback, or event, or notification that I can subscribe to check if a new record is created in the Firebase? If so how would I subscribe to it?

import DS from 'ember-data';

export default DS.Model.extend({
    device: DS.attr('string'),
    userName: DS.attr('string'),
    locationName: DS.attr('string'),
    type: DS.attr('string'),
    fullNameChanged: function() {

      // deal with the change
      console.log("FULL NAME");
    }.observes('device').on('init')
});

My Second approach: Did Create - never called when the changes are made to Firebase directly.

didCreate:function(){
  console.log("Created");
  var mySound = soundManager.createSound({
    url: 'assets/beep22.mp3'
  });
  mySound.play();
},

Did update - called but the property is not persisted

didUpdate:function(){
  console.log("Updated");
  console.log((this.get('shouldPlay')));
}

Did Load - seemed to be the best approach but the changes are not persisted :(

didLoad:function(){
  console.log("Did load");
   if(this.get('shouldPlay')){
     var mySound = soundManager.createSound({
     url: 'assets/beep22.mp3'
  });
  mySound.play();
  this.set('shouldPlay','false');
  this.save().then(() => {
      console.log("saved");
  },(error)=>{
      console.log(error);
  });

}

}

Update:

 this.set('shouldPlay','false'); 

should be

this.set('shouldPlay',false);

This is how it finally worked.


Solution

  • When firebase adds new record into the store it's actually loaded not created. So you can use didLoad hook on ember model. I would also suggest creating service to play sounds. It will make things easier down the road.

    // models/help-request.js
    import DS from 'ember-data';
    import Ember from 'ember';
    const {inject: {service}} = Ember;
    
    export default DS.Model.extend({
      soundPlayer: service(),
    
      didLoad() {
        this._super(...arguments);
        this.get('soundPlayer').newHelpRequest(this);
      },
    });
    
    // services/sound-player.js
    import Ember from 'ember';
    
    export default Ember.Service.extend({
      init() {
        this._super(...arguments);
    
        const beep = soundManager.createSound({
          url: 'assets/beep22.mp3',
        });
        this.set('beep', beep);
      }
    
      play(sound) {
        this.get(sound).play();
      },
    
      newHelpRequest(helpRequest) {
        if (!helpRequest.get('_didNotify')) {
          helpRequest.set('_didNotify', true);
          this.play('beep');
        }
      },
    });