mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-28 12:15:44 +08:00
push updates
This commit is contained in:
129
packages/database/e2e/issues.e2e.js
Normal file
129
packages/database/e2e/issues.e2e.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('./helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/issues`;
|
||||
|
||||
describe('database issues', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('#100 array should return null where key is missing', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/issue_100`);
|
||||
|
||||
const data = {
|
||||
1: {
|
||||
someKey: 'someValue',
|
||||
someOtherKey: 'someOtherValue',
|
||||
},
|
||||
2: {
|
||||
someKey: 'someValue',
|
||||
someOtherKey: 'someOtherValue',
|
||||
},
|
||||
3: {
|
||||
someKey: 'someValue',
|
||||
someOtherKey: 'someOtherValue',
|
||||
},
|
||||
};
|
||||
|
||||
await ref.set(data);
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
snapshot
|
||||
.val()
|
||||
.should.eql(
|
||||
jet.contextify([
|
||||
null,
|
||||
jet.contextify(data[1]),
|
||||
jet.contextify(data[2]),
|
||||
jet.contextify(data[3]),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
describe('#108 filters correctly by float values', () => {
|
||||
it('returns filtered results', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/issue_108/filter`);
|
||||
|
||||
const data = {
|
||||
foobar: {
|
||||
name: 'Foobar Pizzas',
|
||||
latitude: 34.1013717,
|
||||
},
|
||||
notTheFoobar: {
|
||||
name: "Not the pizza you're looking for",
|
||||
latitude: 34.456787,
|
||||
},
|
||||
notAFloat: {
|
||||
name: 'Not a float',
|
||||
latitude: 37,
|
||||
},
|
||||
};
|
||||
|
||||
await ref.set(data);
|
||||
const snapshot = await ref
|
||||
.orderByChild('latitude')
|
||||
.startAt(34.00867000999119)
|
||||
.endAt(34.17462960866099)
|
||||
.once('value');
|
||||
|
||||
const val = snapshot.val();
|
||||
val.foobar.should.eql(jet.contextify(data.foobar));
|
||||
|
||||
should.equal(Object.keys(val).length, 1);
|
||||
});
|
||||
|
||||
it('returns correct results when not using float values', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/issue_108/integer`);
|
||||
|
||||
const data = {
|
||||
foobar: {
|
||||
name: 'Foobar Pizzas',
|
||||
latitude: 34.1013717,
|
||||
},
|
||||
notTheFoobar: {
|
||||
name: "Not the pizza you're looking for",
|
||||
latitude: 34.456787,
|
||||
},
|
||||
notAFloat: {
|
||||
name: 'Not a float',
|
||||
latitude: 37,
|
||||
},
|
||||
};
|
||||
|
||||
await ref.set(data);
|
||||
const snapshot = await ref
|
||||
.orderByChild('latitude')
|
||||
.equalTo(37)
|
||||
.once('value');
|
||||
|
||||
const val = snapshot.val();
|
||||
|
||||
val.notAFloat.should.eql(jet.contextify(data.notAFloat));
|
||||
|
||||
should.equal(Object.keys(val).length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('#489 reutrns long numbers correctly', async () => {
|
||||
const LONG = 1508777379000;
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/issue_489`);
|
||||
await ref.set(LONG);
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql(LONG);
|
||||
});
|
||||
});
|
||||
@@ -55,6 +55,22 @@ describe('database().ref().onDisconnect().update()', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if update paths are not valid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect()
|
||||
.update({
|
||||
$$$$: 'foo',
|
||||
});
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' contains an invalid path.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
|
||||
@@ -15,12 +15,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// const { PATH, seed, wipe } = require('../helpers');
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
// const TEST_PATH = `${PATH}/push`;
|
||||
const TEST_PATH = `${PATH}/push`;
|
||||
|
||||
xdescribe('database().ref().push()', () => {
|
||||
describe.only('database().ref().push()', () => {
|
||||
// before(() => seed(TEST_PATH));
|
||||
// after(() => wipe(TEST_PATH));
|
||||
// TODO
|
||||
|
||||
it('wraps Firebase.push when no value is passed', () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/boop`);
|
||||
const pushed = ref.push();
|
||||
return pushed
|
||||
.then(childRef => {
|
||||
pushed.ref.parent.toString().should.eql(ref.toString());
|
||||
pushed.toString().should.eql(childRef.toString());
|
||||
return pushed.once('value');
|
||||
})
|
||||
.then(snap => {
|
||||
should.equal(snap.val(), null);
|
||||
snap.ref.toString().should.eql(pushed.toString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +51,21 @@ describe('database().ref().update()', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if update paths are not valid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.update({
|
||||
$$$$: 'foo',
|
||||
});
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' contains an invalid path.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
isNumber,
|
||||
isObject,
|
||||
isString,
|
||||
isValidPath,
|
||||
isUndefined,
|
||||
promiseWithOptionalCallback,
|
||||
} from '@react-native-firebase/common';
|
||||
@@ -125,7 +126,14 @@ export default class DatabaseOnDisconnect {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO validate keys; / . # $ |
|
||||
const keys = Object.keys(values);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (!isValidPath(keys[i])) {
|
||||
throw new Error(
|
||||
`firebase.database().onDisconnect().update(*) 'values' contains an invalid path. Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isUndefined(onComplete) && !isFunction(onComplete)) {
|
||||
throw new Error(
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
pathParent,
|
||||
pathChild,
|
||||
isValidPath,
|
||||
// generateDatabaseId,
|
||||
generateDatabaseId,
|
||||
isNumber,
|
||||
isNull,
|
||||
isUndefined,
|
||||
@@ -35,6 +35,7 @@ import DatabaseQuery from './DatabaseQuery';
|
||||
import DatabaseQueryModifiers from './DatabaseQueryModifiers';
|
||||
import DatabaseOnDisconnect from './DatabaseOnDisconnect';
|
||||
import DatabaseDataSnapshot from './DatabaseDataSnapshot';
|
||||
import DatabaseThenableReference from './DatabaseThenableReference';
|
||||
|
||||
const internalRefs = ['.info/connected', '.info/serverTimeOffset'];
|
||||
|
||||
@@ -113,7 +114,14 @@ export default class DatabaseReference extends DatabaseQuery {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO validate keys
|
||||
const keys = Object.keys(values);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (!isValidPath(keys[i])) {
|
||||
throw new Error(
|
||||
`firebase.database().update(*) 'values' contains an invalid path. Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isUndefined(onComplete) && !isFunction(onComplete)) {
|
||||
throw new Error(
|
||||
@@ -250,15 +258,32 @@ export default class DatabaseReference extends DatabaseQuery {
|
||||
* @param onComplete
|
||||
* @returns {DatabaseReference}
|
||||
*/
|
||||
// push(value, onComplete) {
|
||||
// TODO validate value?
|
||||
//
|
||||
// const id = generateDatabaseId(this._database._serverTime);
|
||||
// const pushRef = this.child(id);
|
||||
// const thennablePushRef = this.child(id);
|
||||
//
|
||||
// return thennablePushRef;
|
||||
// }
|
||||
push(value, onComplete) {
|
||||
if (!isUndefined(onComplete) && !isFunction(onComplete)) {
|
||||
throw new Error('TODO');
|
||||
}
|
||||
|
||||
const id = generateDatabaseId(this._database._serverTime);
|
||||
|
||||
if (isUndefined(value) || isNull(value)) {
|
||||
return new DatabaseThenableReference(
|
||||
this._database,
|
||||
pathChild(this.path, id),
|
||||
Promise.resolve(this.child(id)),
|
||||
);
|
||||
}
|
||||
|
||||
const pushRef = this.child(id);
|
||||
|
||||
const promise = pushRef.set(value, onComplete).then(() => pushRef);
|
||||
|
||||
// Prevent unhandled promise rejection if onComplete is passed
|
||||
if (onComplete) {
|
||||
promise.catch(() => {});
|
||||
}
|
||||
|
||||
return new DatabaseThenableReference(this._database, pathChild(this.path, id), promise);
|
||||
}
|
||||
|
||||
/**
|
||||
* @url https://firebase.google.com/docs/reference/js/firebase.database.Reference#ondisconnect
|
||||
|
||||
33
packages/database/lib/DatabaseThenableReference.js
Normal file
33
packages/database/lib/DatabaseThenableReference.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import DatabaseReference from './DatabaseReference';
|
||||
|
||||
export default class DatabaseThenableReference extends DatabaseReference {
|
||||
constructor(database, path, promise) {
|
||||
super(database, path);
|
||||
this._promise = promise;
|
||||
}
|
||||
|
||||
get then() {
|
||||
return this._promise.then.bind(this._promise);
|
||||
}
|
||||
|
||||
get catch() {
|
||||
return this._promise.catch.bind(this._promise);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user