Comparing version 1.1.3 to 1.2.2
@@ -0,1 +1,10 @@ | ||
/*! | ||
* EmberFire is the officially supported adapter for using Firebase with | ||
* Ember Data. The DS.FirebaseAdapter provides all of the standard DS.Adapter | ||
* methods and will automatically synchronize the store with Firebase. | ||
* | ||
* EmberFire 0.0.0 | ||
* https://github.com/firebase/emberfire/ | ||
* License: MIT | ||
*/ | ||
(function() { | ||
@@ -10,3 +19,3 @@ "use strict"; | ||
var EmberFire = Ember.Namespace.create({ | ||
VERSION: '1.1.3' | ||
VERSION: '0.0.0' | ||
}); | ||
@@ -213,3 +222,5 @@ | ||
if (store.hasRecordForId(type, id)) { | ||
store.dematerializeRecord(record); | ||
adapter._enqueue(function() { | ||
store.dematerializeRecord(record); | ||
}); | ||
} | ||
@@ -216,0 +227,0 @@ var error = new Error(fmt('no record was found at %@', [ref.toString()])); |
@@ -1,1 +0,10 @@ | ||
!function(){"use strict";if(void 0!==window.DS){var a=Ember.Namespace.create({VERSION:"1.1.3"});Ember.libraries&&Ember.libraries.registerCoreLibrary("EmberFire",a.VERSION);var b=Ember.RSVP.Promise,c=Ember.EnumerableUtils.map,d=Ember.EnumerableUtils.forEach,e=Ember.String.fmt;DS.FirebaseSerializer=DS.JSONSerializer.extend(Ember.Evented,{normalize:function(a,b){return a.eachRelationship(function(c,d){if("hasMany"===d.kind)if("object"!=typeof b[c]||Ember.isArray(b[c])||d.options.embedded===!0){if(Ember.isArray(b[c]))throw new Error(e('%@ relationship %@(\'%@\') must be a key/value map in Firebase. Example: { "%@": { "%@_id": true } }',[a.toString(),d.kind,d.type.typeKey,d.key,d.type.typeKey]))}else b[c]=Ember.keys(b[c])}),this._super.apply(this,arguments)},extractSingle:function(a,b,c){var d=(a.adapterFor(b),this.normalize(b,c));return b.eachRelationship(function(f,g){if(!Ember.isNone(c)&&!Ember.isNone(c[f])&&g.options.embedded===!0){var h,i,j=d[f],k=[];if("belongsTo"===g.kind){if("string"!=typeof j.id)throw new Error(e('Embedded relationship "%@" of "%@" must contain an "id" property in the payload',[g.type.typeKey,b]));k.push(j),d[f]=j.id}else{for(h in j)i=j[h],null!==i&&"object"==typeof i&&(i.id=h),k.push(i);d[f]=Ember.keys(d[f])}a.pushMany(g.type,k)}}),d},extractArray:function(a,b,d){return c(d,function(c){return this.extractSingle(a,b,c)},this)},serializeHasMany:function(a,b,c){var d=c.key,e=this.keyForRelationship?this.keyForRelationship(d,"hasMany"):d,f=DS.RelationshipChange.determineRelationshipType(a.constructor,c),g=["manyToNone","manyToMany","manyToOne"];g.indexOf(f)>-1&&(b[e]=Ember.A(a.get(d)).mapBy("id"))}}),DS.FirebaseAdapter=DS.Adapter.extend(Ember.Evented,{defaultSerializer:"-firebase",init:function(){if(!this.firebase||"object"!=typeof this.firebase)throw new Error("Please set the `firebase` property on the adapter.");this._ref=this.firebase.ref(),this._findAllMapForType={},this._recordCacheForType={},this._queue=[]},generateIdForRecord:function(){return this._ref.push().name()},_assignIdToPayload:function(a){var b=a.val();return null!==b&&"object"==typeof b&&"undefined"==typeof b.id&&(b.id=a.name()),b},find:function(a,c,d){var f=this,g=!1,h=this._getRef(c,d),i=a.serializerFor(c);return new b(function(b,j){h.on("value",function(k){var l=f._assignIdToPayload(k),m=a.getById(c,k.name());if(f._updateRecordCacheForType(c,l),g)null===l&&m&&!m.get("isDeleted")?f._enqueue(function(){a.getById(c,k.name()).deleteRecord()}):null!==l&&f._enqueue(function(){a.push(c,i.extractSingle(a,c,l))});else if(g=!0,null===l){a.hasRecordForId(c,d)&&a.dematerializeRecord(m);var n=new Error(e("no record was found at %@",[h.toString()]));n.recordId=d,f._enqueue(j,[n])}else f._enqueue(b,[l])},function(a){g||f._enqueue(j,[a])})},e("DS: FirebaseAdapter#find %@ to %@",[c,h.toString()]))},findMany:function(a,b,e){var f=c(e,function(c){return this.find(a,b,c)},this);return Ember.RSVP.allSettled(f).then(function(c){return c=Ember.A(c),d(c.filterBy("state","rejected"),function(c){var d=c.reason.recordId;if(a.hasRecordForId(b,d)){var e=a.getById(b,d);a.dematerializeRecord(e)}}),Ember.A(c.filterBy("state","fulfilled")).mapBy("value")})},findAll:function(a,c){var d=this,f=this._getRef(c);return new b(function(b,e){var g;d._findAllHasEventsForType(c)||(g=d._findAllAddEventListeners(a,c,f)),f.once("value",function(a){var e=[];g&&Ember.run(null,g.resolve),null===a.val()?d._enqueue(b,[e]):(a.forEach(function(a){var b=d._assignIdToPayload(a);d._updateRecordCacheForType(c,b),e.push(b)}),d._enqueue(b,[e]))},function(a){d._enqueue(e,[a])})},e("DS: FirebaseAdapter#findAll %@ to %@",[c,f.toString()]))},_findAllMapForType:void 0,_findAllHasEventsForType:function(a){return!Ember.isNone(this._findAllMapForType[a])},_findAllAddEventListeners:function(a,b,c){this._findAllMapForType[b]=!0;var d=Ember.RSVP.defer(),e=this,f=a.serializerFor(b),g=!1;return d.promise.then(function(){g=!0}),c.on("child_added",function(c){g&&e._handleChildValue(a,b,f,c)}),c.on("child_changed",function(c){g&&e._handleChildValue(a,b,f,c)}),c.on("child_removed",function(c){if(g){var d=a.getById(b,c.name());d&&!d.get("isDeleted")&&e._enqueue(function(){a.deleteRecord(d)})}}),d},_handleChildValue:function(a,b,c,d){var e=this._assignIdToPayload(d);this._enqueue(function(){a.push(b,c.extractSingle(a,b,e))})},createRecord:function(a,b,c){return this.updateRecord(a,b,c)},updateRecord:function(a,c,d){var f=this,g=this._getRef(c,d.id),h=Ember.get(f._recordCacheForType,e("%@.%@",[c.typeKey,d.get("id")]))||{};return this._getSerializedRecord(d).then(function(i){return new b(function(b,j){var k=Ember.A();d.eachRelationship(function(b,d){var e;switch(d.kind){case"hasMany":Ember.isArray(i[b])&&(e=f._saveHasManyRelationship(a,c,d,i[b],g,h),k.push(e),delete i[b]);break;case"belongsTo":"undefined"==typeof i[b]||null===i[b]||""===i[b]?delete i[b]:d.options.embedded===!0&&(e=f._saveBelongsToRecord(a,c,d,i[b],g),k.push(e),delete i[b])}}),Ember.RSVP.allSettled(k).then(function(a){a=Ember.A(a);var h=Ember.A(a.filterBy("state","rejected"));if(0!==h.get("length")){var k=new Error(e("Some errors were encountered while saving %@ %@",[c,d.id]));k.errors=h.mapBy("reason"),f._enqueue(j,[k])}g.update(i,function(a){a?f._enqueue(j,[a]):f._enqueue(b)})})})},e("DS: FirebaseAdapter#updateRecord %@ to %@",[c,g.toString()]))},_getSerializedRecord:function(a){var c=a.serialize({includeId:!1}),d=[];return a.eachRelationship(function(e,f){switch(f.kind){case"hasMany":d.push(b.cast(a.get(e)).then(function(a){c[e]=Ember.A(a).mapBy("id")}))}}),Ember.RSVP.all(d).then(function(){return c})},_saveHasManyRelationship:function(a,b,c,d,f,g){if(!Ember.isArray(d))throw new Error("hasMany relationships must must be an array");var h=this,i=Ember.A(g[c.key]);d=Ember.A(d);var j=d.filter(function(a){return!i.contains(a)}),k=d.filter(function(b){var d=c.type;return a.hasRecordForId(d,b)&&a.getById(d,b).get("isDirty")===!0});k=Ember.A(k.concat(j)).uniq().map(function(b){return h._saveHasManyRecord(a,c,f,b)});var l=i.filter(function(a){return!d.contains(a)});l=Ember.A(l).map(function(b){return h._removeHasManyRecord(a,c,f,b)});var m=k.concat(l);return Ember.RSVP.allSettled(m).then(function(a){var b=Ember.A(Ember.A(a).filterBy("state","rejected"));if(0===b.get("length"))return g[c.key]=d,a;var f=new Error(e("Some errors were encountered while saving a hasMany relationship %@ -> %@",[c.parentType,c.type]));throw f.errors=Ember.A(b).mapBy("reason"),f})},_saveHasManyRecord:function(a,c,d,e){var f=this,g=this._getRelationshipRef(d,c.key,e),h=a.getById(c.type,e),i=c.options.embedded===!0,j=i?h.serialize({includeId:!1}):!0;return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=g.toString()),f._enqueue(b,[c])):f._enqueue(a)};i?g.update(j,c):g.set(j,c)})},_removeHasManyRecord:function(a,c,d,e){var f=this,g=this._getRelationshipRef(d,c.key,e);return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=g.toString()),f._enqueue(b,[c])):f._enqueue(a)};g.remove(c)})},_saveBelongsToRecord:function(a,c,d,e,f){var g=this,h=f.child(d.key),i=a.getById(d.type,e),j=d.options.embedded===!0,k=j?i.serialize({includeId:!0}):!0;return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=h.toString()),g._enqueue(b,[c])):g._enqueue(a)};j?h.update(k,c):h.set(k,c)})},deleteRecord:function(a,c,d){var f=this,g=this._getRef(c,d.get("id"));return new b(function(a,b){g.remove(function(c){c?f._enqueue(b,[c]):f._enqueue(a)})},e("DS: FirebaseAdapter#deleteRecord %@ to %@",[c,g.toString()]))},pathForType:function(a){var b=Ember.String.camelize(a);return Ember.String.pluralize(b)},_getRef:function(a,b){var c=this._ref;return a&&(c=c.child(this.pathForType(a.typeKey))),b&&(c=c.child(b)),c},_getRelationshipRef:function(a,b,c){return a.child(b).child(c)},_queueFlushDelay:1e3/60,_queueScheduleFlush:function(){Ember.run.later(this,this._queueFlush,this._queueFlushDelay)},_queueFlush:function(){d(this._queue,function(a){var b=a[0],c=a[1];b.apply(null,c)}),this._queue.length=0},_enqueue:function(a,b){var c=this._queue.push([a,b]);1===c&&this._queueScheduleFlush()},_recordCacheForType:void 0,_updateRecordCacheForType:function(a,b){if(b){var c=this,d=b.id,e=c._recordCacheForType,f=a.typeKey;a.eachRelationship(function(a,c){if("hasMany"===c.kind){var g=b[a];e[f]=e[f]||{},e[f][d]=e[f][d]||{},e[f][d][a]=Ember.isNone(g)?Ember.A():Ember.A(Ember.keys(g))}})}}}),Ember.onLoad("Ember.Application",function(a){a.initializer({name:"firebase",initialize:function(a,b){b.register("adapter:-firebase",DS.FirebaseAdapter),b.register("serializer:-firebase",DS.FirebaseSerializer)}})})}}(); | ||
/*! | ||
* EmberFire is the officially supported adapter for using Firebase with | ||
* Ember Data. The DS.FirebaseAdapter provides all of the standard DS.Adapter | ||
* methods and will automatically synchronize the store with Firebase. | ||
* | ||
* EmberFire 0.0.0 | ||
* https://github.com/firebase/emberfire/ | ||
* License: MIT | ||
*/ | ||
!function(){"use strict";if(void 0!==window.DS){var a=Ember.Namespace.create({VERSION:"0.0.0"});Ember.libraries&&Ember.libraries.registerCoreLibrary("EmberFire",a.VERSION);var b=Ember.RSVP.Promise,c=Ember.EnumerableUtils.map,d=Ember.EnumerableUtils.forEach,e=Ember.String.fmt;DS.FirebaseSerializer=DS.JSONSerializer.extend(Ember.Evented,{normalize:function(a,b){return a.eachRelationship(function(c,d){if("hasMany"===d.kind)if("object"!=typeof b[c]||Ember.isArray(b[c])||d.options.embedded===!0){if(Ember.isArray(b[c]))throw new Error(e('%@ relationship %@(\'%@\') must be a key/value map in Firebase. Example: { "%@": { "%@_id": true } }',[a.toString(),d.kind,d.type.typeKey,d.key,d.type.typeKey]))}else b[c]=Ember.keys(b[c])}),this._super.apply(this,arguments)},extractSingle:function(a,b,c){var d=(a.adapterFor(b),this.normalize(b,c));return b.eachRelationship(function(f,g){if(!Ember.isNone(c)&&!Ember.isNone(c[f])&&g.options.embedded===!0){var h,i,j=d[f],k=[];if("belongsTo"===g.kind){if("string"!=typeof j.id)throw new Error(e('Embedded relationship "%@" of "%@" must contain an "id" property in the payload',[g.type.typeKey,b]));k.push(j),d[f]=j.id}else{for(h in j)i=j[h],null!==i&&"object"==typeof i&&(i.id=h),k.push(i);d[f]=Ember.keys(d[f])}a.pushMany(g.type,k)}}),d},extractArray:function(a,b,d){return c(d,function(c){return this.extractSingle(a,b,c)},this)},serializeHasMany:function(a,b,c){var d=c.key,e=this.keyForRelationship?this.keyForRelationship(d,"hasMany"):d,f=DS.RelationshipChange.determineRelationshipType(a.constructor,c),g=["manyToNone","manyToMany","manyToOne"];g.indexOf(f)>-1&&(b[e]=Ember.A(a.get(d)).mapBy("id"))}}),DS.FirebaseAdapter=DS.Adapter.extend(Ember.Evented,{defaultSerializer:"-firebase",init:function(){if(!this.firebase||"object"!=typeof this.firebase)throw new Error("Please set the `firebase` property on the adapter.");this._ref=this.firebase.ref(),this._findAllMapForType={},this._recordCacheForType={},this._queue=[]},generateIdForRecord:function(){return this._ref.push().name()},_assignIdToPayload:function(a){var b=a.val();return null!==b&&"object"==typeof b&&"undefined"==typeof b.id&&(b.id=a.name()),b},find:function(a,c,d){var f=this,g=!1,h=this._getRef(c,d),i=a.serializerFor(c);return new b(function(b,j){h.on("value",function(k){var l=f._assignIdToPayload(k),m=a.getById(c,k.name());if(f._updateRecordCacheForType(c,l),g)null===l&&m&&!m.get("isDeleted")?f._enqueue(function(){a.getById(c,k.name()).deleteRecord()}):null!==l&&f._enqueue(function(){a.push(c,i.extractSingle(a,c,l))});else if(g=!0,null===l){a.hasRecordForId(c,d)&&f._enqueue(function(){a.dematerializeRecord(m)});var n=new Error(e("no record was found at %@",[h.toString()]));n.recordId=d,f._enqueue(j,[n])}else f._enqueue(b,[l])},function(a){g||f._enqueue(j,[a])})},e("DS: FirebaseAdapter#find %@ to %@",[c,h.toString()]))},findMany:function(a,b,e){var f=c(e,function(c){return this.find(a,b,c)},this);return Ember.RSVP.allSettled(f).then(function(c){return c=Ember.A(c),d(c.filterBy("state","rejected"),function(c){var d=c.reason.recordId;if(a.hasRecordForId(b,d)){var e=a.getById(b,d);a.dematerializeRecord(e)}}),Ember.A(c.filterBy("state","fulfilled")).mapBy("value")})},findAll:function(a,c){var d=this,f=this._getRef(c);return new b(function(b,e){var g;d._findAllHasEventsForType(c)||(g=d._findAllAddEventListeners(a,c,f)),f.once("value",function(a){var e=[];g&&Ember.run(null,g.resolve),null===a.val()?d._enqueue(b,[e]):(a.forEach(function(a){var b=d._assignIdToPayload(a);d._updateRecordCacheForType(c,b),e.push(b)}),d._enqueue(b,[e]))},function(a){d._enqueue(e,[a])})},e("DS: FirebaseAdapter#findAll %@ to %@",[c,f.toString()]))},_findAllMapForType:void 0,_findAllHasEventsForType:function(a){return!Ember.isNone(this._findAllMapForType[a])},_findAllAddEventListeners:function(a,b,c){this._findAllMapForType[b]=!0;var d=Ember.RSVP.defer(),e=this,f=a.serializerFor(b),g=!1;return d.promise.then(function(){g=!0}),c.on("child_added",function(c){g&&e._handleChildValue(a,b,f,c)}),c.on("child_changed",function(c){g&&e._handleChildValue(a,b,f,c)}),c.on("child_removed",function(c){if(g){var d=a.getById(b,c.name());d&&!d.get("isDeleted")&&e._enqueue(function(){a.deleteRecord(d)})}}),d},_handleChildValue:function(a,b,c,d){var e=this._assignIdToPayload(d);this._enqueue(function(){a.push(b,c.extractSingle(a,b,e))})},createRecord:function(a,b,c){return this.updateRecord(a,b,c)},updateRecord:function(a,c,d){var f=this,g=this._getRef(c,d.id),h=Ember.get(f._recordCacheForType,e("%@.%@",[c.typeKey,d.get("id")]))||{};return this._getSerializedRecord(d).then(function(i){return new b(function(b,j){var k=Ember.A();d.eachRelationship(function(b,d){var e;switch(d.kind){case"hasMany":Ember.isArray(i[b])&&(e=f._saveHasManyRelationship(a,c,d,i[b],g,h),k.push(e),delete i[b]);break;case"belongsTo":"undefined"==typeof i[b]||null===i[b]||""===i[b]?delete i[b]:d.options.embedded===!0&&(e=f._saveBelongsToRecord(a,c,d,i[b],g),k.push(e),delete i[b])}}),Ember.RSVP.allSettled(k).then(function(a){a=Ember.A(a);var h=Ember.A(a.filterBy("state","rejected"));if(0!==h.get("length")){var k=new Error(e("Some errors were encountered while saving %@ %@",[c,d.id]));k.errors=h.mapBy("reason"),f._enqueue(j,[k])}g.update(i,function(a){a?f._enqueue(j,[a]):f._enqueue(b)})})})},e("DS: FirebaseAdapter#updateRecord %@ to %@",[c,g.toString()]))},_getSerializedRecord:function(a){var c=a.serialize({includeId:!1}),d=[];return a.eachRelationship(function(e,f){switch(f.kind){case"hasMany":d.push(b.cast(a.get(e)).then(function(a){c[e]=Ember.A(a).mapBy("id")}))}}),Ember.RSVP.all(d).then(function(){return c})},_saveHasManyRelationship:function(a,b,c,d,f,g){if(!Ember.isArray(d))throw new Error("hasMany relationships must must be an array");var h=this,i=Ember.A(g[c.key]);d=Ember.A(d);var j=d.filter(function(a){return!i.contains(a)}),k=d.filter(function(b){var d=c.type;return a.hasRecordForId(d,b)&&a.getById(d,b).get("isDirty")===!0});k=Ember.A(k.concat(j)).uniq().map(function(b){return h._saveHasManyRecord(a,c,f,b)});var l=i.filter(function(a){return!d.contains(a)});l=Ember.A(l).map(function(b){return h._removeHasManyRecord(a,c,f,b)});var m=k.concat(l);return Ember.RSVP.allSettled(m).then(function(a){var b=Ember.A(Ember.A(a).filterBy("state","rejected"));if(0===b.get("length"))return g[c.key]=d,a;var f=new Error(e("Some errors were encountered while saving a hasMany relationship %@ -> %@",[c.parentType,c.type]));throw f.errors=Ember.A(b).mapBy("reason"),f})},_saveHasManyRecord:function(a,c,d,e){var f=this,g=this._getRelationshipRef(d,c.key,e),h=a.getById(c.type,e),i=c.options.embedded===!0,j=i?h.serialize({includeId:!1}):!0;return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=g.toString()),f._enqueue(b,[c])):f._enqueue(a)};i?g.update(j,c):g.set(j,c)})},_removeHasManyRecord:function(a,c,d,e){var f=this,g=this._getRelationshipRef(d,c.key,e);return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=g.toString()),f._enqueue(b,[c])):f._enqueue(a)};g.remove(c)})},_saveBelongsToRecord:function(a,c,d,e,f){var g=this,h=f.child(d.key),i=a.getById(d.type,e),j=d.options.embedded===!0,k=j?i.serialize({includeId:!0}):!0;return new b(function(a,b){var c=function(c){c?("object"==typeof c&&(c.location=h.toString()),g._enqueue(b,[c])):g._enqueue(a)};j?h.update(k,c):h.set(k,c)})},deleteRecord:function(a,c,d){var f=this,g=this._getRef(c,d.get("id"));return new b(function(a,b){g.remove(function(c){c?f._enqueue(b,[c]):f._enqueue(a)})},e("DS: FirebaseAdapter#deleteRecord %@ to %@",[c,g.toString()]))},pathForType:function(a){var b=Ember.String.camelize(a);return Ember.String.pluralize(b)},_getRef:function(a,b){var c=this._ref;return a&&(c=c.child(this.pathForType(a.typeKey))),b&&(c=c.child(b)),c},_getRelationshipRef:function(a,b,c){return a.child(b).child(c)},_queueFlushDelay:1e3/60,_queueScheduleFlush:function(){Ember.run.later(this,this._queueFlush,this._queueFlushDelay)},_queueFlush:function(){d(this._queue,function(a){var b=a[0],c=a[1];b.apply(null,c)}),this._queue.length=0},_enqueue:function(a,b){var c=this._queue.push([a,b]);1===c&&this._queueScheduleFlush()},_recordCacheForType:void 0,_updateRecordCacheForType:function(a,b){if(b){var c=this,d=b.id,e=c._recordCacheForType,f=a.typeKey;a.eachRelationship(function(a,c){if("hasMany"===c.kind){var g=b[a];e[f]=e[f]||{},e[f][d]=e[f][d]||{},e[f][d][a]=Ember.isNone(g)?Ember.A():Ember.A(Ember.keys(g))}})}}}),Ember.onLoad("Ember.Application",function(a){a.initializer({name:"firebase",initialize:function(a,b){b.register("adapter:-firebase",DS.FirebaseAdapter),b.register("serializer:-firebase",DS.FirebaseSerializer)}})})}}(); |
{ | ||
"name": "emberfire", | ||
"description": "The officially supported Ember binding for Firebase", | ||
"version": "1.1.3", | ||
"version": "1.2.2", | ||
"author": "Firebase <support@firebase.com> (https://www.firebase.com/)", | ||
@@ -32,7 +32,6 @@ "homepage": "https://github.com/firebase/emberfire/", | ||
"README.md", | ||
"CHANGELOG.md", | ||
"package.json" | ||
], | ||
"ember-addon": { | ||
"main": "lib/ember-cli-ember-fire.js" | ||
"main": "lib/ember-addon/index.js" | ||
}, | ||
@@ -60,4 +59,5 @@ "dependencies": { | ||
"scripts": { | ||
"test": "grunt test" | ||
"test": "grunt test", | ||
"travis": "grunt" | ||
} | ||
} |
154
README.md
# EmberFire (Firebase + Ember Data) | ||
[![Build Status](https://travis-ci.org/firebase/emberfire.svg)](https://travis-ci.org/firebase/emberfire) | ||
[![Build Status](https://travis-ci.org/firebase/emberfire.svg?branch=master)](https://travis-ci.org/firebase/emberfire) | ||
[![Version](https://badge.fury.io/gh/firebase%2Femberfire.svg)](http://badge.fury.io/gh/firebase%2Femberfire) | ||
**EmberFire is currently using Ember Data v1.0.0-beta.8. We're in the process of updating it to support the latest version (beta.10).** | ||
EmberFire is the officially supported adapter for using | ||
@@ -10,7 +12,10 @@ [Firebase](http://www.firebase.com/?utm_medium=web&utm_source=emberfire) with | ||
The `DS.FirebaseAdapter` provides all of the standard `DS.Adapter` methods and will automatically synchronize the store with Firebase. | ||
The `DS.FirebaseAdapter` provides all of the standard `DS.Adapter` methods and will automatically | ||
synchronize the store with Firebase. | ||
If you would like to use Firebase without Ember Data, we recommend the third-party [ember-firebase](https://github.com/mjijackson/ember-firebase) binding. | ||
If you would like to use Firebase without Ember Data, we recommend the third-party | ||
[ember-firebase](https://github.com/mjijackson/ember-firebase) binding. | ||
**Join the [Firebase + Ember Google Group](https://groups.google.com/forum/#!forum/firebase-ember) to ask technical questions, share apps you've built, and chat with other developers in the community.** | ||
**Join the [Firebase + Ember Google Group](https://groups.google.com/forum/#!forum/firebase-ember) | ||
to ask technical questions, share apps you've built, and chat with other developers in the community.** | ||
@@ -28,3 +33,3 @@ | ||
<!-- Firebase --> | ||
<script src="https://cdn.firebase.com/js/client/1.0.17/firebase.js"></script> | ||
<script src="https://cdn.firebase.com/js/client/1.0.21/firebase.js"></script> | ||
@@ -35,5 +40,10 @@ <!-- EmberFire --> | ||
Use the URL above to download both the minified and non-minified versions of EmberFire from the Firebase CDN. You can also download them from the `/dist/` directory of this GitHub repository. [Firebase](https://www.firebase.com/docs/web-quickstart.html?utm_medium=web&utm_source=emberfire) and [Ember](http://emberjs.com/guides/getting-started/obtaining-emberjs-and-dependencies/) can be downloaded directly from their respective websites. | ||
Use the URL above to download both the minified and non-minified versions of EmberFire from the | ||
Firebase CDN. You can also download them from the | ||
[releases page of this GitHub repository](https://github.com/firebase/emberfire/releases). | ||
[Firebase](https://www.firebase.com/docs/web/quickstart.html?utm_medium=web&utm_source=emberfire) and | ||
[Ember](http://emberjs.com/guides/getting-started/obtaining-emberjs-and-dependencies/) can be | ||
downloaded directly from their respective websites. | ||
You can also install EmberFire via Bower and the dependencies will be downloaded automatically: | ||
You can also install EmberFire via Bower and its dependencies will be downloaded automatically: | ||
@@ -46,31 +56,35 @@ ```bash | ||
EmberFire requires Firebase in order to sync data. You can [sign up here](https://www.firebase.com/docs/web-quickstart.html?utm_medium=web&utm_source=emberfire) for a free account. | ||
EmberFire requires Firebase in order to sync data. You can | ||
[sign up here](https://www.firebase.com/signup/?utm_medium=web&utm_source=emberfire) for a free | ||
account. | ||
## Usage | ||
To get started, simply create an instance of the | ||
`DS.FirebaseAdapter` in your app: | ||
To get started, simply create an instance of the `DS.FirebaseAdapter` in your app: | ||
```js | ||
```javascript | ||
App.ApplicationAdapter = DS.FirebaseAdapter.extend({ | ||
firebase: new Firebase('https://<my-firebase>.firebaseio.com') | ||
firebase: new Firebase("https://<your-firebase>.firebaseio.com") | ||
}); | ||
``` | ||
Your Firebase data will now be synced with the Ember Data store | ||
Your Firebase data will now be synced with the Ember Data store. | ||
You can now interact with the data store as you normally would. For example, | ||
calling `find()` with a specific ID will retrieve that record from Firebase. | ||
Additionally, from that point on, every time that record is updated in Firebase, | ||
it will automatically be updated in the local data store. | ||
You can now interact with the data store as you normally would. For example, calling `find()` with | ||
a specific ID will retrieve that record from Firebase. Additionally, from that point on, every time | ||
that record is updated in Firebase, it will automatically be updated in the local data store. | ||
See the [Ember documentation](http://emberjs.com/guides/models/) for a full | ||
list of methods, including ways to create, find, delete and query records. | ||
See the [Ember documentation](http://emberjs.com/guides/models/) for a full list of methods, | ||
including ways to create, find, delete and query records. | ||
#### Ember CLI | ||
EmberFire also works with the Ember CLI. Run the following command to add `emberfire.js` to your project: | ||
EmberFire also works with the Ember CLI [Example App](https://github.com/stefanpenner/ember-cli-ember-fire). Run the following command to add `emberfire.js` to your project: | ||
Temporary install instructions for ember-cli: | ||
```bash | ||
$ npm install --save emberfire | ||
$ npm install emberfire --save-dev | ||
$ ember generate emberfire | ||
``` | ||
@@ -84,3 +98,3 @@ | ||
export default DS.FirebaseAdapter.extend({ | ||
firebase: new Firebase('https://<my-firebase>.firebaseio.com') | ||
firebase: new Firebase("https://<your-firebase>.firebaseio.com") | ||
}); | ||
@@ -91,3 +105,3 @@ ``` | ||
By default, EmberFire will try to determine the correct Firebase reference based on the model name | ||
By default, EmberFire will try to determine the correct Firebase reference based on the model name. | ||
@@ -98,7 +112,7 @@ ```javascript | ||
// Records will be fetched from to https://<my-firebase>.firebaseio.com/posts | ||
var posts = store.findAll('post'); | ||
// Records will be fetched from to https://<your-firebase>.firebaseio.com/posts | ||
var posts = store.findAll("post"); | ||
// The new record will be saved to https://<my-firebase>.firebaseio.com/posts/post_id | ||
var newPost = store.createRecord('post').save(); | ||
// The new record will be saved to https://<your-firebase>.firebaseio.com/posts/post_id | ||
var newPost = store.createRecord("post").save(); | ||
``` | ||
@@ -108,3 +122,4 @@ | ||
If you would like to customize where a model will be fetched/saved, simply create a model-specific adapter: | ||
If you would like to customize where a model will be fetched/saved, simply create a model-specific | ||
adapter: | ||
@@ -118,3 +133,3 @@ ```javascript | ||
pathForType: function(type) { | ||
return 'custom-posts'; | ||
return "custom-posts"; | ||
} | ||
@@ -124,10 +139,11 @@ }); | ||
Overriding the `pathForType` method will allow you to tell the adapter where it should fetch/save records of the specified type | ||
Overriding the `pathForType()` method will allow you to tell the adapter where it should fetch/save | ||
records of the specified type. | ||
```javascript | ||
// Records will now be fetched from to https://<my-firebase>.firebaseio.com/custom-posts | ||
var posts = store.findAll('post'); | ||
// Records will now be fetched from to https://<your-firebase>.firebaseio.com/custom-posts | ||
var posts = store.findAll("post"); | ||
// The new record will now be saved to https://<my-firebase>.firebaseio.com/custom-posts/post_id | ||
var newPost = store.createRecord('post').save(); | ||
// The new record will now be saved to https://<your-firebase>.firebaseio.com/custom-posts/post_id | ||
var newPost = store.createRecord("post").save(); | ||
``` | ||
@@ -141,20 +157,18 @@ | ||
Any relationship that is flagged as `async: true` tells the adapter to fetch | ||
the record if it hasn't already been loaded | ||
Any relationship that is flagged as `async: true` tells the adapter to fetch the record if it | ||
hasn't already been loaded. | ||
```js | ||
```javascript | ||
App.Post = DS.Model.extend({ | ||
comments: DS.hasMany('comment', { async: true }) | ||
comments: DS.hasMany("comment", { async: true }) | ||
}); | ||
App.Comment = DS.Model.extend({ | ||
post: DS.belongsTo('post', { async: true }) | ||
post: DS.belongsTo("post", { async: true }) | ||
}); | ||
``` | ||
In the `App.Post` example, comments will be fetched from | ||
`https://<my-firebase>.firebaseio.com/comments` | ||
In the `App.Post` example, comments will be fetched from `https://<your-firebase>.firebaseio.com/comments`. | ||
Here is what the data structure would look like in Firebase: | ||
Here is what the data structure would look in Firebase: | ||
```json | ||
@@ -169,3 +183,2 @@ { | ||
}, | ||
"comments": { | ||
@@ -180,17 +193,18 @@ "comment_id_1": { | ||
**Note:** If your async data isn't autoloading, make sure you've defined your relationships in both directions. | ||
**Note:** If your async data isn't auto-loading, make sure you've defined your relationships in | ||
both directions. | ||
#### Embedded | ||
Any relationship that is flagged as `embedded: true` tells the adapter | ||
that the related records have been included in the payload. | ||
Any relationship that is flagged as `embedded: true` tells the adapter that the related records | ||
have been included in the payload. | ||
Generally, this approach is more complicated and not as widely used, | ||
but it has been included to support existing data structures. | ||
Generally, this approach is more complicated and not as widely used, but it has been included to | ||
support existing data structures. | ||
##### hasMany | ||
##### `hasMany()` | ||
```js | ||
```javascript | ||
App.Post = DS.Model.extend({ | ||
comments: DS.hasMany('comment', { embedded: true }) | ||
comments: DS.hasMany("comment", { embedded: true }) | ||
}); | ||
@@ -218,3 +232,3 @@ ``` | ||
```js | ||
var comment = store.createRecord('comment'); | ||
var comment = store.createRecord("comment"); | ||
// This WILL NOT save the comment inside of the post because the adapter doesn't know | ||
@@ -225,15 +239,15 @@ // where to save the comment without the context of the post | ||
Instead, the comment needs to be added to the post | ||
and then the post can be saved | ||
Instead, the comment needs to be added to the post and then the post can be saved: | ||
```js | ||
// Add the new comment to the post and save it | ||
post.get('comments').addObject(comment); | ||
post.get("comments").addObject(comment); | ||
// Saving the post will save the embedded comments | ||
post.save() | ||
post.save(); | ||
``` | ||
##### belongsTo | ||
##### `belongsTo()` | ||
Any embedded `belongsTo` relationship must specifiy an id property in the payload | ||
Any embedded `belongsTo()` relationship must specify an `id` property in the payload: | ||
@@ -254,16 +268,20 @@ ```json | ||
If you'd like to contribute to EmberFire, you'll need to run the following commands to get your environment set up: | ||
If you'd like to contribute to EmberFire, you'll need to run the following commands to get your | ||
environment set up: | ||
```bash | ||
$ git clone https://github.com/firebase/emberfire.git | ||
$ cd emberfire # go to the emberfire directory | ||
$ npm install -g grunt # globally install grunt task runner | ||
$ npm install -g bower # globally install Bower package manager | ||
$ npm install # install local npm build / test dependencies | ||
$ bower install # install local JavaScript dependencies | ||
$ grunt watch # watch for source file changes | ||
$ cd emberfire # go to the emberfire directory | ||
$ npm install -g grunt-cli # globally install grunt task runner | ||
$ npm install -g bower # globally install Bower package manager | ||
$ npm install # install local npm build / test dependencies | ||
$ bower install # install local JavaScript dependencies | ||
$ grunt watch # watch for source file changes | ||
``` | ||
`grunt watch` will watch for changes in the `/src/` directory and lint, concatenate, and minify the source files and run the test suite when a change occurs. The output files - `emberfire.js` and `emberfire.min.js` - are written to the `/dist/` directory. | ||
`grunt watch` will watch for changes in the `/src/` directory and lint, concatenate, and minify the | ||
source files and run the test suite when a change occurs. The output files - `emberfire.js` and | ||
`emberfire.min.js` - are written to the `/dist/` directory. | ||
You can run the test suite by navigating to `file:///path/to/emberfire/test/index.html` or via the command line using `grunt test`. | ||
You can run the test suite by navigating to `file:///path/to/emberfire/test/index.html` or via the | ||
command line using `grunt test`. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
485262
10
10667
272
0
4