[firestore][js] implement Blob support
This commit is contained in:
parent
5906d20ce0
commit
9c49d9ef57
|
@ -1,32 +1,40 @@
|
|||
import Base64 from './utils/Base64';
|
||||
|
||||
type BlobFormat = 'string' | 'array';
|
||||
|
||||
export default class Blob {
|
||||
_data: Uint8Array | string;
|
||||
_type: BlobFormat;
|
||||
_binaryString: string;
|
||||
|
||||
constructor(data, type: BlobFormat) {
|
||||
this._data = data;
|
||||
this._type = type;
|
||||
constructor(binaryString) {
|
||||
this._binaryString = binaryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Blob from the given Base64 string
|
||||
*
|
||||
* @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#.fromBase64String
|
||||
* @param base64 string
|
||||
*/
|
||||
static fromBase64String(base64: string): Blob {
|
||||
return new Blob(base64, 'string');
|
||||
return new Blob(Base64.atob(base64));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Blob from the given Uint8Array.
|
||||
*
|
||||
* @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#.fromUint8Array
|
||||
* @param array Array
|
||||
*/
|
||||
static fromUint8Array(array: Uint8Array): Blob {
|
||||
return new Blob(array, 'array');
|
||||
if (!(array instanceof Uint8Array)) {
|
||||
throw new Error(
|
||||
'firestore.Blob.fromUint8Array expects an instance of Uint8Array'
|
||||
);
|
||||
}
|
||||
|
||||
return new Blob(
|
||||
Array.prototype.map
|
||||
.call(array, (char: number) => String.fromCharCode(char))
|
||||
.join('')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,45 +44,42 @@ export default class Blob {
|
|||
* @returns boolean 'true' if this Blob is equal to the provided one.
|
||||
*/
|
||||
isEqual(blob: Blob): boolean {
|
||||
let thisBlobBase64 = '';
|
||||
if (this._type === 'string') thisBlobBase64 = this._data;
|
||||
else thisBlobBase64 = this.toBase64();
|
||||
if (!(blob instanceof Blob)) {
|
||||
throw new Error('firestore.Blob.isEqual expects an instance of Blob');
|
||||
}
|
||||
|
||||
let thatBlobBase64 = '';
|
||||
if (blob._type === 'string') thatBlobBase64 = blob._data;
|
||||
else thatBlobBase64 = blob.toBase64();
|
||||
|
||||
return thisBlobBase64 === thatBlobBase64;
|
||||
return this._binaryString === blob._binaryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bytes of a Blob as a Base64-encoded string.
|
||||
*
|
||||
* @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#toBase64
|
||||
* @returns string The Base64-encoded string created from the Blob object.
|
||||
*/
|
||||
toBase64(): string {
|
||||
if (this._type === 'string') return this._data;
|
||||
|
||||
let binary = '';
|
||||
const len = this._data.byteLength;
|
||||
for (let i = 0; i < len; i++) {
|
||||
binary += String.fromCharCode(this._data[i]);
|
||||
}
|
||||
|
||||
return Base64.btoa(binary);
|
||||
return Base64.btoa(this._binaryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bytes of a Blob in a new Uint8Array.
|
||||
*
|
||||
* @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#toUint8Array
|
||||
* @returns non-null Uint8Array The Uint8Array created from the Blob object.
|
||||
*/
|
||||
toUint8Array(): Uint8Array {
|
||||
if (this._type === 'array') return this._data;
|
||||
return new Uint8Array(
|
||||
Base64.atob(this._data)
|
||||
.split('')
|
||||
.map(c => c.charCodeAt(0))
|
||||
this._binaryString.split('').map(c => c.charCodeAt(0))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this blob instance
|
||||
*
|
||||
* @returns {string}
|
||||
* @memberof Blob
|
||||
*/
|
||||
toString(): string {
|
||||
return `firestore.Blob(base64: ${this.toBase64()})`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import DocumentReference from './DocumentReference';
|
|||
import FieldPath from './FieldPath';
|
||||
import FieldValue from './FieldValue';
|
||||
import GeoPoint from './GeoPoint';
|
||||
import Blob from './Blob';
|
||||
import Path from './Path';
|
||||
import WriteBatch from './WriteBatch';
|
||||
import TransactionHandler from './TransactionHandler';
|
||||
|
@ -258,6 +259,7 @@ export const statics = {
|
|||
FieldPath,
|
||||
FieldValue,
|
||||
GeoPoint,
|
||||
Blob,
|
||||
enableLogging(enabled: boolean): void {
|
||||
// DEPRECATED: Remove method in v4.1.0
|
||||
console.warn(
|
||||
|
|
|
@ -42,6 +42,7 @@ export type NativeTypeMap = {
|
|||
| 'array'
|
||||
| 'boolean'
|
||||
| 'date'
|
||||
| 'blob'
|
||||
| 'documentid'
|
||||
| 'fieldvalue'
|
||||
| 'geopoint'
|
||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
|||
|
||||
if (charCode > 0xff) {
|
||||
throw new Error(
|
||||
"'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."
|
||||
"'firestore.utils.btoa' failed: The string to be encoded contains characters outside of the Latin1 range."
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ export default {
|
|||
|
||||
if (str.length % 4 === 1) {
|
||||
throw new Error(
|
||||
"'atob' failed: The string to be decoded is not correctly encoded."
|
||||
"'firestore.utils.atob' failed: The string to be decoded is not correctly encoded."
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
import DocumentReference from '../DocumentReference';
|
||||
import Blob from '../Blob';
|
||||
import { DOCUMENT_ID } from '../FieldPath';
|
||||
import {
|
||||
DELETE_FIELD_VALUE,
|
||||
|
@ -98,6 +99,11 @@ export const buildTypeMap = (value: any): NativeTypeMap | null => {
|
|||
type: 'date',
|
||||
value: value.getTime(),
|
||||
};
|
||||
} else if (value instanceof Blob) {
|
||||
return {
|
||||
type: 'blob',
|
||||
value: value.toBase64(),
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: 'object',
|
||||
|
@ -156,6 +162,8 @@ const parseTypeMap = (firestore: Firestore, typeMap: NativeTypeMap): any => {
|
|||
return new GeoPoint(value.latitude, value.longitude);
|
||||
} else if (type === 'date') {
|
||||
return new Date(value);
|
||||
} else if (type === 'blob') {
|
||||
return Blob.fromBase64String(value);
|
||||
}
|
||||
console.warn(`Unknown data type received ${type}`);
|
||||
return value;
|
||||
|
|
Loading…
Reference in New Issue