Skip to content

Commit 5a29425

Browse files
committed
fix(firestore, bytes): return Bytes for modular API usage, fix deprecation
- deprecation warnings were still emitted because internally Bytes and Blob were confused - now with a simple type inheritance trick, Bytes *is* FirestoreBlob, so at a low-level we always return Bytes (so modular works), and at a high level we just construct Bytes carefully so it is still a FirestoreBlob and doesn't do extra parsing
1 parent c3b582f commit 5a29425

File tree

6 files changed

+38
-27
lines changed

6 files changed

+38
-27
lines changed

packages/firestore/e2e/Bytes.e2e.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*
1616
*/
1717

18+
import FirestoreBlob from '../lib/FirestoreBlob';
19+
1820
const testObject = { hello: 'world' };
1921
const testString = JSON.stringify(testObject);
2022
const testBuffer = [123, 34, 104, 101, 108, 108, 111, 34, 58, 34, 119, 111, 114, 108, 100, 34, 125];
@@ -25,12 +27,12 @@ describe('Bytes modular', function () {
2527
const { Bytes } = firestoreModular;
2628
const myBytes = Bytes.fromBase64String(testBase64);
2729
myBytes.should.be.instanceOf(Bytes);
28-
myBytes._blob.should.be.instanceOf(firebase.firestore.Blob);
29-
myBytes._blob._binaryString.should.equal(testString);
30+
myBytes.should.be.instanceOf(FirestoreBlob);
31+
myBytes._binaryString.should.equal(testString);
3032
should.deepEqual(
31-
JSON.parse(myBytes._blob._binaryString),
33+
JSON.parse(myBytes._binaryString),
3234
testObject,
33-
'Expected Blob _binaryString internals to serialize to json and match test object',
35+
'Expected Bytes _binaryString internals to serialize to json and match test object',
3436
);
3537
});
3638

@@ -47,7 +49,7 @@ describe('Bytes modular', function () {
4749
const { Bytes } = firestoreModular;
4850
const myBytes = Bytes.fromUint8Array(testUInt8Array);
4951
myBytes.should.be.instanceOf(Bytes);
50-
const json = JSON.parse(myBytes._blob._binaryString);
52+
const json = JSON.parse(myBytes._binaryString);
5153
json.hello.should.equal('world');
5254
});
5355

packages/firestore/e2e/DocumentSnapshot/data.e2e.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ describe('firestore().doc() -> snapshot.data()', function () {
183183
// });
184184

185185
it('handles all data types', async function () {
186-
const { getFirestore, doc, setDoc, getDoc, deleteDoc } = firestoreModular;
186+
const { getFirestore, doc, setDoc, getDoc, deleteDoc, Timestamp, Bytes, GeoPoint } =
187+
firestoreModular;
187188
const types = {
188189
string: '123456',
189190
stringEmpty: '',
@@ -196,11 +197,11 @@ describe('firestore().doc() -> snapshot.data()', function () {
196197
map: {}, // set after
197198
array: [], // set after,
198199
nullValue: null,
199-
timestamp: new firebase.firestore.Timestamp(123, 123456),
200+
timestamp: new Timestamp(123, 123456),
200201
date: new Date(),
201-
geopoint: new firebase.firestore.GeoPoint(1, 2),
202-
reference: firebase.firestore().doc(`${COLLECTION}/foobar`),
203-
blob: firebase.firestore.Blob.fromBase64String(blobBase64),
202+
geopoint: new GeoPoint(1, 2),
203+
reference: doc(getFirestore(), `${COLLECTION}/foobar`),
204+
bytes: Bytes.fromBase64String(blobBase64),
204205
};
205206

206207
const map = { foo: 'bar' };
@@ -246,24 +247,27 @@ describe('firestore().doc() -> snapshot.data()', function () {
246247
should.equal(data.nullValue, null);
247248

248249
// Timestamp
249-
data.timestamp.should.be.an.instanceOf(firebase.firestore.Timestamp);
250+
data.timestamp.should.be.an.instanceOf(Timestamp);
250251
data.timestamp.seconds.should.be.a.Number();
251252
data.timestamp.nanoseconds.should.be.a.Number();
252-
data.date.should.be.an.instanceOf(firebase.firestore.Timestamp);
253+
data.date.should.be.an.instanceOf(Timestamp);
253254
data.date.seconds.should.be.a.Number();
254255
data.date.nanoseconds.should.be.a.Number();
255256

256257
// GeoPoint
257-
data.geopoint.should.be.an.instanceOf(firebase.firestore.GeoPoint);
258+
data.geopoint.should.be.an.instanceOf(GeoPoint);
258259
data.geopoint.latitude.should.be.a.Number();
259260
data.geopoint.longitude.should.be.a.Number();
260261

261262
// Reference
262263
// data.reference.should.be.an.instanceOf();
263264
data.reference.path.should.equal(`${COLLECTION}/foobar`);
264265

265-
// Blob
266-
data.blob.toBase64.should.be.a.Function();
266+
// Bytes
267+
data.bytes.should.be.an.instanceOf(Bytes);
268+
types.bytes.isEqual(data.bytes);
269+
data.bytes.isEqual(types.bytes);
270+
data.bytes.toBase64.should.be.a.Function();
267271

268272
await deleteDoc(ref);
269273
});

packages/firestore/lib/FirestoreBlob.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import { Base64, isString } from '@react-native-firebase/app/lib/common';
1919

2020
export default class FirestoreBlob {
21-
constructor(internal = false, binaryString) {
21+
constructor(internal = false, binaryString = undefined) {
2222
if (internal === false) {
2323
throw new Error(
2424
'firebase.firestore.Blob constructor is private, use Blob.<field>() instead.',

packages/firestore/lib/modular/Bytes.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export declare class Bytes {
1+
export declare class Bytes extends FirestoreBlob {
22
static fromBase64String(base64: string): Bytes;
33

44
static fromUint8Array(array: Uint8Array): Bytes;
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,48 @@
1-
import { firebase } from '../index';
1+
import FirestoreBlob from '../FirestoreBlob';
22

33
/**
44
* An immutable object representing an array of bytes.
55
*/
6-
export class Bytes {
6+
export class Bytes extends FirestoreBlob {
77
/**
88
* @hideconstructor
99
* @param {firebase.firestore.Blob} blob
1010
*/
1111
constructor(blob) {
12-
this._blob = blob;
12+
super(true);
13+
// binary string was already parsed and created, potentially expensive
14+
// don't parse it again, just set it into the new FirebaseBlob
15+
this._binaryString = blob._binaryString;
1316
}
1417

1518
/**
1619
* @param {string} base64
1720
* @returns {Bytes}
1821
*/
1922
static fromBase64String(base64) {
20-
return new Bytes(firebase.firestore.Blob.fromBase64String(base64));
23+
return new Bytes(FirestoreBlob.fromBase64String(base64));
2124
}
2225

2326
/**
2427
* @param {Uint8Array} array
2528
* @returns {Bytes}
2629
*/
2730
static fromUint8Array(array) {
28-
return new Bytes(firebase.firestore.Blob.fromUint8Array(array));
31+
return new Bytes(FirestoreBlob.fromUint8Array(array));
2932
}
3033

3134
/**
3235
* @returns {string}
3336
*/
3437
toBase64() {
35-
return this._blob.toBase64();
38+
return super.toBase64();
3639
}
3740

3841
/**
3942
* @returns {Uint8Array}
4043
*/
4144
toUint8Array() {
42-
return this._blob.toUint8Array();
45+
return super.toUint8Array();
4346
}
4447

4548
/**
@@ -54,6 +57,6 @@ export class Bytes {
5457
* @returns {boolean}
5558
*/
5659
isEqual(other) {
57-
return this._blob.isEqual(other._blob);
60+
return super.isEqual(other);
5861
}
5962
}

packages/firestore/lib/utils/serialize.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import FirestoreGeoPoint from '../FirestoreGeoPoint';
3131
import FirestorePath from '../FirestorePath';
3232
import FirestoreTimestamp from '../FirestoreTimestamp';
3333
import { getTypeMapInt, getTypeMapName } from './typemap';
34+
import { Bytes } from '../modular/Bytes';
3435

3536
// To avoid React Native require cycle warnings
3637
let FirestoreDocumentReference = null;
@@ -179,7 +180,8 @@ export function generateNativeData(value, ignoreUndefined) {
179180
return getTypeMapInt('timestamp', [value.seconds, value.nanoseconds]);
180181
}
181182

182-
if (value instanceof FirestoreBlob) {
183+
// Modular API uses Bytes instead of Blob
184+
if (value instanceof FirestoreBlob || value instanceof Bytes) {
183185
return getTypeMapInt('blob', value.toBase64());
184186
}
185187

@@ -276,7 +278,7 @@ export function parseNativeData(firestore, nativeArray) {
276278
case 'timestamp':
277279
return new FirestoreTimestamp(value[0], value[1]);
278280
case 'blob':
279-
return FirestoreBlob.fromBase64String(value);
281+
return Bytes.fromBase64String(value);
280282
default:
281283
// eslint-disable-next-line no-console
282284
console.warn(`Unknown data type received from native channel: ${type}`);

0 commit comments

Comments
 (0)