Skip to content

chore(storage): deprecation warnings for v8 API ahead of future major… #8566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/app/lib/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,35 @@ const mapOfDeprecationReplacements = {
nanoseconds: NO_REPLACEMENT,
},
},
storage: {
default: {
useEmulator: 'connectStorageEmulator()',
ref: 'ref()',
refFromURL: 'refFromURL()',
setMaxOperationRetryTime: 'setMaxOperationRetryTime()',
setMaxUploadRetryTime: 'setMaxUploadRetryTime()',
setMaxDownloadRetryTime: 'setMaxDownloadRetryTime()',
},
StorageReference: {
delete: 'deleteObject()',
getDownloadURL: 'getDownloadURL()',
getMetadata: 'getMetadata()',
list: 'list()',
listAll: 'listAll()',
updateMetadata: 'updateMetadata()',
put: 'uploadBytesResumable()',
putString: 'uploadString()',
putFile: 'putFile()',
writeToFile: 'writeToFile()',
toString: 'toString()',
child: 'child()',
},
statics: {
StringFormat: 'StringFormat',
TaskEvent: 'TaskEvent',
TaskState: 'TaskState',
},
},
};

const modularDeprecationMessage =
Expand Down Expand Up @@ -274,6 +303,10 @@ function getNamespace(target) {
if (target._config && target._config.namespace) {
return target._config.namespace;
}
if (target.constructor.name === 'StorageReference') {
return 'storage';
}

const className = target.name ? target.name : target.constructor.name;
return Object.keys(mapOfDeprecationReplacements).find(key => {
if (mapOfDeprecationReplacements[key][className]) {
Expand All @@ -291,6 +324,11 @@ function getInstanceName(target) {
// module class instance, we use default to store map of deprecated methods
return 'default';
}

if (target.constructor.name === 'StorageReference') {
// if path passed into ref(), it will pass in the arg as target.name
return target.constructor.name;
}
if (target.name) {
// It's a function which has a name property unlike classes
return target.name;
Expand Down Expand Up @@ -332,6 +370,9 @@ export function createDeprecationProxy(instance) {
if (prop === 'CustomProvider') {
deprecationConsoleWarning('appCheck', prop, 'statics', false);
}
if (prop === 'StringFormat' || prop === 'TaskEvent' || prop === 'TaskState') {
deprecationConsoleWarning('storage', prop, 'statics', false);
}

if (prop !== 'setLogLevel') {
// we want to capture setLogLevel function call which we do below
Expand Down
253 changes: 252 additions & 1 deletion packages/storage/__tests__/storage.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
import { afterAll, beforeAll, beforeEach, describe, expect, it, jest } from '@jest/globals';

import storage, {
firebase,
Expand Down Expand Up @@ -30,6 +30,14 @@ import storage, {
TaskState,
} from '../lib';

import {
createCheckV9Deprecation,
CheckV9DeprecationFunction,
} from '../../app/lib/common/unitTestUtils';

// @ts-ignore test
import FirebaseModule from '../../app/lib/internal/FirebaseModule';

describe('Storage', function () {
describe('namespace', function () {
beforeAll(async function () {
Expand Down Expand Up @@ -196,4 +204,247 @@ describe('Storage', function () {
expect(TaskState.SUCCESS).toBeDefined();
});
});

describe('test `console.warn` is called for RNFB v8 API & not called for v9 API', function () {
let storageV9Deprecation: CheckV9DeprecationFunction;
let storageRefV9Deprecation: CheckV9DeprecationFunction;
let staticsV9Deprecation: CheckV9DeprecationFunction;

beforeEach(function () {
storageV9Deprecation = createCheckV9Deprecation(['storage']);

storageRefV9Deprecation = createCheckV9Deprecation(['storage', 'StorageReference']);

staticsV9Deprecation = createCheckV9Deprecation(['storage', 'statics']);

// @ts-ignore test
jest.spyOn(FirebaseModule.prototype, 'native', 'get').mockImplementation(() => {
return new Proxy(
{},
{
get: (_target, prop) => {
// Handle list operations specially
if (prop === 'list' || prop === 'listAll') {
return jest.fn().mockResolvedValue({
items: [],
prefixes: [],
nextPageToken: null,
} as never);
}
// Default mock for other operations
return jest.fn().mockResolvedValue({
source: 'cache',
changes: [],
documents: [],
metadata: {},
path: 'foo',
} as never);
},
},
);
});
});

describe('Storage', function () {
it('useStorageEmulator()', function () {
const storage = getStorage();
storageV9Deprecation(
() => connectStorageEmulator(storage, 'localhost', 8080),
() => storage.useEmulator('localhost', 8080),
'useEmulator',
);
});

it('ref()', function () {
const storage = getStorage();
storageV9Deprecation(
() => ref(storage, 'foo'),
() => storage.ref('foo'),
'ref',
);
});

it('refFromURL()', function () {
const storage = firebase.app().storage();
storageV9Deprecation(
() => refFromURL(storage, 'gs://flutterfire-e2e-tests.appspot.com/flutter-tsts'),
() => storage.refFromURL('gs://flutterfire-e2e-tests.appspot.com/flutter-tsts'),
'refFromURL',
);
});

it('setMaxOperationRetryTime()', function () {
const storage = firebase.app().storage();
storageV9Deprecation(
() => setMaxOperationRetryTime(storage, 1000),
() => storage.setMaxOperationRetryTime(1000),
'setMaxOperationRetryTime',
);
});

it('setMaxUploadRetryTime()', function () {
const storage = firebase.app().storage();
storageV9Deprecation(
() => setMaxUploadRetryTime(storage, 1000),
() => storage.setMaxUploadRetryTime(1000),
'setMaxUploadRetryTime',
);
});

it('setMaxDownloadRetryTime()', function () {
const storage = firebase.app().storage();
storageV9Deprecation(
() => setMaxDownloadRetryTime(storage, 1000),
() => storage.setMaxDownloadRetryTime(1000),
'setMaxDownloadRetryTime',
);
});

it('delete()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => deleteObject(storageRef),
() => storageRef.delete(),
'delete',
);
});

it('getDownloadURL()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => getDownloadURL(storageRef),
() => storageRef.getDownloadURL(),
'getDownloadURL',
);
});

it('getMetadata()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => getMetadata(storageRef),
() => storageRef.getMetadata(),
'getMetadata',
);
});

it('list()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => list(storageRef),
() => storageRef.list(),
'list',
);
});

it('listAll()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => listAll(storageRef),
() => storageRef.listAll(),
'listAll',
);
});

it('updateMetadata()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => updateMetadata(storageRef, {}),
() => storageRef.updateMetadata({}),
'updateMetadata',
);
});

it('put()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => uploadBytesResumable(storageRef, new Blob(['foo']), {}),
() => storageRef.put(new Blob(['foo']), {}),
'put',
);
});

it('putString()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => uploadString(storageRef, 'foo', StringFormat.RAW),
() => storageRef.putString('foo', StringFormat.RAW),
'putString',
);
});

it('putFile()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => putFile(storageRef, 'foo', {}),
() => storageRef.putFile('foo', {}),
'putFile',
);
});

it('writeToFile()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => writeToFile(storageRef, 'foo'),
() => storageRef.writeToFile('foo'),
'writeToFile',
);
});

it('toString()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => toString(storageRef),
() => storageRef.toString(),
'toString',
);
});

it('child()', function () {
const storage = firebase.app().storage();
const storageRef = storage.ref('foo');
storageRefV9Deprecation(
() => child(storageRef, 'bar'),
() => storageRef.child('bar'),
'child',
);
});
});

describe('statics', function () {
it('StringFormat static', function () {
staticsV9Deprecation(
() => StringFormat.RAW,
() => firebase.storage.StringFormat.RAW,
'StringFormat',
);
});

it('TaskEvent static', function () {
staticsV9Deprecation(
() => TaskEvent.STATE_CHANGED,
() => firebase.storage.TaskEvent.STATE_CHANGED,
'TaskEvent',
);
});

it('TaskState static', function () {
staticsV9Deprecation(
() => TaskState.SUCCESS,
() => firebase.storage.TaskState.SUCCESS,
'TaskState',
);
});
});
});
});
13 changes: 6 additions & 7 deletions packages/storage/e2e/StorageReference.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ describe('storage() -> StorageReference', function () {
const storageReference = firebase.storage().ref(`${PATH}/deleteMe.txt`);
await storageReference.putString('Delete File');
await storageReference.delete();

try {
await storageReference.getMetadata();
return Promise.reject(new Error('Did not throw'));
Expand Down Expand Up @@ -717,16 +716,16 @@ describe('storage() -> StorageReference', function () {
// Same bucket defined in app.js when setting up emulator

it('should write a file to the second storage bucket', async function () {
const { ref } = storageModular;
const { ref, uploadString } = storageModular;

// "only-second-bucket" is not an allowable path on live project for either bucket
const storageReference = ref(secondStorage, 'only-second-bucket/ok.txt');

await storageReference.putString('Hello World');
await uploadString(storageReference, 'Hello World');
});

it('should throw exception on path not allowed on second bucket security rules', async function () {
const { ref } = storageModular;
const { ref, uploadString } = storageModular;

// "react-native-firebase-testing" is not an allowed on second bucket, only "ony-second-bucket"
const storageReference = ref(
Expand All @@ -735,7 +734,7 @@ describe('storage() -> StorageReference', function () {
);

try {
await storageReference.putString('Hello World');
await uploadString(storageReference, 'Hello World');
return Promise.reject(new Error('Did not throw'));
} catch (error) {
error.code.should.equal('storage/unauthorized');
Expand Down Expand Up @@ -974,10 +973,10 @@ describe('storage() -> StorageReference', function () {

describe('list', function () {
it('should return list results', async function () {
const { getStorage, ref } = storageModular;
const { getStorage, ref, list } = storageModular;
const storageReference = ref(getStorage(), `${PATH}/list`);

const result = await storageReference.list();
const result = await list(storageReference);

result.constructor.name.should.eql('StorageListResult');
result.should.have.property('nextPageToken');
Expand Down
Loading
Loading