diff --git a/README.md b/README.md
index 4d1d03a..ded1195 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,14 @@ workflows.
Example Usage:
```html
+
+
```
diff --git a/firebase-database-behavior.html b/firebase-database-behavior.html
index 0cf7108..60c38af 100644
--- a/firebase-database-behavior.html
+++ b/firebase-database-behavior.html
@@ -46,7 +46,23 @@
disabled: {
type: Boolean,
value: false
- }
+ },
+
+ /**
+ * `exists` is set to `true` when the data actually exists for the
+ * specified path; `false` otherwise.
+ * When we are unable to determine whether data exists or not
+ * (e.g. first round trip to the server not yet performed) the value
+ * is `null`
+ */
+ exists: {
+ type: Boolean,
+ notify: true,
+ value: null,
+ readOnly: true,
+ reflectToAttribute: true
+ },
+
},
observers: [
@@ -95,6 +111,8 @@
},
__pathChanged: function(path, oldPath) {
+ this._setExists(null);
+
if (!this.disabled && !this.valueIsEmpty(this.data)) {
this.syncToMemory(function() {
this.data = this.zeroValue;
diff --git a/firebase-document.html b/firebase-document.html
index d0538b1..3bfc618 100644
--- a/firebase-document.html
+++ b/firebase-document.html
@@ -160,11 +160,13 @@
__onFirebaseValue: function(snapshot) {
var value = snapshot.val();
+ var exists = true;
if (value == null) {
value = this.zeroValue;
this.__needSetData = true;
- }
+ exists = false;
+ }
if (!this.isNew) {
this.async(function() {
@@ -188,6 +190,10 @@
}
}
});
+ this._setExists(exists);
+ if(!exists) {
+ this.fire('empty-result');
+ }
});
}
}
diff --git a/firebase-firestore-mixin.html b/firebase-firestore-mixin.html
index a7bcc07..8598ad4 100644
--- a/firebase-firestore-mixin.html
+++ b/firebase-firestore-mixin.html
@@ -169,10 +169,10 @@
this._firestoreProps = {};
this._firestoreListeners = {};
- this.db = this.constructor.db || firebase.firestore();
}
connectedCallback() {
+ super.connectedCallback();
if (this[CONNECTED_CALLBACK_TOKEN] !== true) {
this[CONNECTED_CALLBACK_TOKEN] = true;
@@ -188,8 +188,6 @@
}
}
}
-
- super.connectedCallback();
}
_firestoreBind(name, options) {
@@ -205,6 +203,7 @@
this._firestoreProps[name] = config;
const args = config.props.concat(config.observes);
+ this._firestoreUpdateBinding(name, ...args.map(x => this[x]));
if (args.length > 0) {
// Create a method observer that will be called every time
// a templatized or observed property changes
@@ -212,13 +211,10 @@
`_firestoreUpdateBinding('${name}', ${args.join(',')})`
this._createMethodObserver(observer);
}
-
- this._firestoreUpdateBinding(name, ...args.map(x => this[x]));
}
_firestoreUpdateBinding(name, ...args) {
this._firestoreUnlisten(name);
-
const config = this._firestoreProps[name];
const isDefined = (x) => x !== undefined;
const propArgs = args.slice(0, config.props.length).filter(isDefined);
@@ -229,6 +225,7 @@
observesArgs.length === config.observes.length;
if (propArgsReady && observesArgsReady) {
+ this.db = this.db || firebase.firestore();
const collPath = stitch(config.literals, propArgs);
const assigner = this._firestoreAssigner(name, config);
diff --git a/firebase-query.html b/firebase-query.html
index d503f83..466d0d3 100644
--- a/firebase-query.html
+++ b/firebase-query.html
@@ -289,6 +289,7 @@
this.syncToMemory(function() {
this.__map = {};
this.set('data', this.zeroValue);
+ this._setExists(null);
});
}
@@ -305,13 +306,14 @@
query.off('child_changed', this.__onFirebaseChildChanged, this);
query.off('child_moved', this.__onFirebaseChildMoved, this);
}
-
- this._onOnce = true;
- this._query = query
+
+ this._setExists(null);
+ this._onOnce = true;
+ this._query = query;
// does the on-value first
- query.off('value', this.__onFirebaseValue, this)
- query.on('value', this.__onFirebaseValue, this.__onError, this)
+ query.off('value', this.__onFirebaseValue, this);
+ query.on('value', this.__onFirebaseValue, this.__onError, this);
}
},
@@ -338,6 +340,7 @@
}.bind(this))
this.set('data', data);
+ this._setExists(true);
}
const query = this.query
@@ -371,6 +374,7 @@
this.__map[key] = value;
this.splice('data', previousChildIndex + 1, 0, value);
+ this._setExists(true);
},
__onFirebaseChildRemoved: function(snapshot) {
@@ -390,6 +394,9 @@
this.splice('data', this.__indexFromKey(key), 1);
}
});
+ if (this.data.length === 0) {
+ this._setExists(false);
+ }
});
}
},
diff --git a/firebase-storage-multiupload.html b/firebase-storage-multiupload.html
index d1790b5..31a4422 100644
--- a/firebase-storage-multiupload.html
+++ b/firebase-storage-multiupload.html
@@ -53,7 +53,7 @@
* file-task
*
*
*
+ name="test"
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
diff --git a/test/firebase-common-behavior.html b/test/firebase-common-behavior.html
index 8eba2b9..268ca2e 100644
--- a/test/firebase-common-behavior.html
+++ b/test/firebase-common-behavior.html
@@ -23,23 +23,23 @@
+ name="test"
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
+ name="alt"
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
diff --git a/test/firebase-database-behavior.html b/test/firebase-database-behavior.html
index f3efa47..fe2053b 100644
--- a/test/firebase-database-behavior.html
+++ b/test/firebase-database-behavior.html
@@ -23,10 +23,10 @@
+ name="test"
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
diff --git a/test/firebase-document.html b/test/firebase-document.html
index b97adcf..f5979a0 100644
--- a/test/firebase-document.html
+++ b/test/firebase-document.html
@@ -24,10 +24,10 @@
+ name="test"
+ api-key="AIzaSyDTP-eiQezleFsV2WddFBAhF_WEzx_8v_g"
+ auth-domain="polymerfire-test.firebaseapp.com"
+ database-url="https://polymerfire-test.firebaseio.com">
@@ -65,6 +65,59 @@
});
}
});
+
+ function pushFirebaseValue(path, value) {
+ return firebase.app('test').database().ref(path).push(value);
+ }
+
+ function clearFirebaseValue(path) {
+ return firebase.app('test').database().ref(path).set(null);
+ }
+
+ var makeObject;
+ var root;
+
+ setup(function() {
+ var objectId = 0;
+ makeObject = function(value) {
+ return {
+ val: value || objectId++
+ };
+ };
+
+ return pushFirebaseValue('/test', { ignore: 'me' }).then(function(snapshot) {
+ root = '/test/' + snapshot.key;
+ });
+ });
+
+ suite('exists attribute', function() {
+ var query;
+
+ setup(function() {
+ query = fixture('BasicStorage');
+ query.path = root + '/list';
+ return query.transactionsComplete;
+ });
+
+ test('exists is null when we change the path', function() {
+ query.path = '/myNewPath';
+ expect(query.exists).to.be.equal(null);
+ });
+
+ test('exists is true when we have data false when we remove it.', function() {
+ var object = makeObject();
+
+ return pushFirebaseValue(query.path, object).then(function() {
+ expect(query.exists).to.be.equal(true);
+ }).then(function(){
+ clearFirebaseValue(query.path);
+ }).then(function() {
+ expect(query.exists).to.be.equal(false);
+ });
+ });
+
+ });
+
});
diff --git a/test/firebase-query.html b/test/firebase-query.html
index 777e7b5..e0aff54 100644
--- a/test/firebase-query.html
+++ b/test/firebase-query.html
@@ -21,10 +21,10 @@
+ name="test"
+ api-key="AIzaSyBzKhxNa2k9pA3m9_Ji3POFAKyGGFnyshI"
+ auth-domain="note-app-firebase-3a483.firebaseapp.com"
+ database-url="https://note-app-firebase-3a483.firebaseio.com">
@@ -176,6 +176,7 @@
var object = makeObject();
return pushFirebaseValue(query.path, object).then(function() {
+ expect(query.exists).to.be.equal(true);
expect(query.data.length).to.be.equal(1);
expect(query.data[0]).to.be.ok;
expect(query.data[0].val).to.be.equal(object.val);
@@ -241,6 +242,22 @@
expect(query.data[0].foo).to.be.eql(undefined);
});
});
+
+ test('exists is null when template is stamped', function() {
+ expect(query.exists).to.be.equal(null);
+ })
+
+ test('exists is true when we have data false when we remove it.', function() {
+ var object = makeObject();
+
+ return pushFirebaseValue(query.path, object).then(function() {
+ expect(query.exists).to.be.equal(true);
+ }).then(function(){
+ clearFirebaseValue(query.path);
+ }).then(function() {
+ expect(query.exists).to.be.equal(false);
+ });
+ });
});
suite('querying against leaf node collections', function() {