[android][database] Fix hanging db when querying object with large numerical keys

This commit is contained in:
Chris Bianca 2017-06-16 13:10:11 +01:00
parent 61ed7e1e96
commit 2fdb73656e
3 changed files with 62 additions and 9 deletions

View File

@ -213,16 +213,22 @@ public class Utils {
} }
/** /**
* Data should be treated as an array if:
* 1) All the keys are integers
* 2) More than half the keys between 0 and the maximum key in the object have non-empty values
*
* Definition from: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html
* *
* @param snapshot * @param snapshot
* @return * @return
*/ */
private static boolean isArray(DataSnapshot snapshot) { private static boolean isArray(DataSnapshot snapshot) {
long expectedKey = -1; long expectedKey = -1;
long maxAllowedKey = (snapshot.getChildrenCount() * 2) - 1;
for (DataSnapshot child : snapshot.getChildren()) { for (DataSnapshot child : snapshot.getChildren()) {
try { try {
long key = Long.parseLong(child.getKey()); long key = Long.parseLong(child.getKey());
if (key > expectedKey) { if (key > expectedKey && key <= maxAllowedKey) {
expectedKey = key; expectedKey = key;
} else { } else {
return false; return false;
@ -235,16 +241,22 @@ public class Utils {
} }
/** /**
* Data should be treated as an array if:
* 1) All the keys are integers
* 2) More than half the keys between 0 and the maximum key in the object have non-empty values
*
* Definition from: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html
* *
* @param mutableData * @param mutableData
* @return * @return
*/ */
private static boolean isArray(MutableData mutableData) { private static boolean isArray(MutableData mutableData) {
long expectedKey = -1; long expectedKey = -1;
long maxAllowedKey = (mutableData.getChildrenCount() * 2) - 1;
for (MutableData child : mutableData.getChildren()) { for (MutableData child : mutableData.getChildren()) {
try { try {
long key = Long.parseLong(child.getKey()); long key = Long.parseLong(child.getKey());
if (key > expectedKey) { if (key > expectedKey && key <= maxAllowedKey) {
expectedKey++; expectedKey++;
} else { } else {
return false; return false;

View File

@ -1,10 +1,10 @@
import should from 'should'; import should from 'should';
import DatabaseContents from '../../support/DatabaseContents'; import DatabaseContents from '../../support/DatabaseContents';
function issueTests({ fdescribe, describe, it, context, firebase }) { function issueTests({ describe, it, context, firebase }) {
describe('issue_100', () => { describe('issue_100', () => {
context('array-like values should', () => { context('array-like values should', () => {
it('return null in returned array at positions where a key is missing', async() => { it('return null in returned array at positions where a key is missing', async () => {
// Setup // Setup
const ref = firebase.native.database().ref('tests/issues/100'); const ref = firebase.native.database().ref('tests/issues/100');
@ -12,9 +12,6 @@ function issueTests({ fdescribe, describe, it, context, firebase }) {
// Test // Test
return ref.once('value').then((snapshot) => { return ref.once('value').then((snapshot) => {
// Assertion
// console.warn(JSON.stringify(snapshot.val()));
snapshot.val().should.eql([null, DatabaseContents.ISSUES[100][1], DatabaseContents.ISSUES[100][2], DatabaseContents.ISSUES[100][3]]); snapshot.val().should.eql([null, DatabaseContents.ISSUES[100][1], DatabaseContents.ISSUES[100][2], DatabaseContents.ISSUES[100][3]]);
}); });
}); });
@ -23,7 +20,7 @@ function issueTests({ fdescribe, describe, it, context, firebase }) {
describe('issue_108', () => { describe('issue_108', () => {
context('filters using floats', () => { context('filters using floats', () => {
it('return correct results', async() => { it('return correct results', async () => {
// Setup // Setup
const ref = firebase.native.database().ref('tests/issues/108'); const ref = firebase.native.database().ref('tests/issues/108');
@ -45,7 +42,7 @@ function issueTests({ fdescribe, describe, it, context, firebase }) {
}); });
}); });
it('return correct results when not using float values', async() => { it('return correct results when not using float values', async () => {
// Setup // Setup
const ref = firebase.native.database().ref('tests/issues/108'); const ref = firebase.native.database().ref('tests/issues/108');
@ -69,6 +66,22 @@ function issueTests({ fdescribe, describe, it, context, firebase }) {
}); });
}); });
}); });
describe('issue_171', () => {
context('non array-like values should', () => {
it('return as objects', async () => {
// Setup
const ref = firebase.native.database().ref('tests/issues/171');
// Test
return ref.once('value').then((snapshot) => {
snapshot.val().should.eql(DatabaseContents.ISSUES[171]);
});
});
});
});
} }
export default issueTests; export default issueTests;

View File

@ -63,5 +63,33 @@ export default {
latitude: 37, latitude: 37,
}, },
}, },
// https://github.com/invertase/react-native-firebase/issues/171
171: {
10053768200609241: {
email: 'emaila@hotmail.com',
name: 'Sek Ranger',
profile_picture: 'https://url.to/picture',
uid: 'n6V8vACidyW4OKxnELkBbW83JaS2',
},
10053925505239749: {
email: 'emailb@hotmail.com',
name: 'Gu Hungry',
profile_picture: 'https://url.to/picture',
uid: 'Qq4Pwm7H2kO6sJIMLAJxuhAGGh22',
},
10106631429240929: {
email: 'emailc@gmail.com',
name: 'Chwang',
profile_picture: 'https://url.to/picture',
uid: 'T7VVrveS0dPs3idmgetLUfQsLZs1',
},
10106631429240930: {
email: 'emaild@gmail.com',
name: 'Introv Bigs',
profile_picture: 'https://url.to/picture',
uid: 'aNYxLexOb2WsXGOPiEAu47q5bxH3',
},
},
}, },
}; };