Skip to content

feat(storage): support storage.useEmulator, and md5hash metadata on upload #5324

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

Merged
merged 4 commits into from
May 19, 2021
Merged
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
6 changes: 6 additions & 0 deletions .github/workflows/scripts/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"database": {
"rules": "database.rules"
},
"storage": {
"rules": "storage.rules"
},
"emulators": {
"auth": {
"port": "9099"
Expand All @@ -16,6 +19,9 @@
"firestore": {
"port": "8080"
},
"storage": {
"port": "9199"
},
"ui": {
"enabled": true,
"port": 4000
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scripts/start-firebase-emulator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ if ! [ -x "$(command -v firebase)" ]; then
exit 1
fi

EMU_START_COMMAND="firebase emulators:start --only auth,database,firestore --project react-native-firebase-testing"
EMU_START_COMMAND="firebase emulators:start --only auth,database,firestore,storage --project react-native-firebase-testing"
#EMU_START_COMMAND="sleep 120"
MAX_RETRIES=3
MAX_CHECKATTEMPTS=60
Expand Down Expand Up @@ -38,4 +38,4 @@ while [ $RETRIES -le $MAX_RETRIES ]; do

done
echo "Firebase Emulator Suite did not come online after $MAX_RETRIES attempts."
exit 1
exit 1
17 changes: 17 additions & 0 deletions .github/workflows/scripts/storage.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{document=**} {
allow read, write: if false;
}

match /writeOnly.txt {
allow read: if false;
allow write: if true;
}

match /react-native-tests/{document=**} {
allow read, write: if true;
}
}
}
3 changes: 3 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ jest.doMock('react-native', () => {
settings: jest.fn(),
},
RNFBPerfModule: {},
RNFBStorageModule: {
useEmulator: jest.fn(),
},
},
},
ReactNative,
Expand Down
3 changes: 3 additions & 0 deletions packages/app/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export namespace Utils {
* Traditionally this is an SD card, but it may also be implemented as built-in storage on a device.
*
* Returns null if no external storage directory found, e.g. removable media has been ejected by the user.
* Requires special permission granted by Play Store review team on Android, is unlikely to be a valid path.
*
* ```js
* firebase.utils.FilePath.EXTERNAL_STORAGE_DIRECTORY;
Expand All @@ -349,6 +350,7 @@ export namespace Utils {

/**
* Returns an absolute path to a directory in which to place pictures that are available to the user.
* Requires special permission granted by Play Store review team on Android, is unlikely to be a valid path.
*
* ```js
* firebase.utils.FilePath.PICTURES_DIRECTORY;
Expand All @@ -358,6 +360,7 @@ export namespace Utils {

/**
* Returns an absolute path to a directory in which to place movies that are available to the user.
* Requires special permission granted by Play Store review team on Android, is unlikely to be a valid path.
*
* ```js
* firebase.utils.FilePath.MOVIES_DIRECTORY;
Expand Down
2 changes: 0 additions & 2 deletions packages/app/lib/internal/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const APP_NATIVE_MODULE = 'RNFBAppModule';
export const DEFAULT_APP_NAME = '[DEFAULT]';

export const KNOWN_NAMESPACES = [
'admob',
'auth',
'analytics',
'remoteConfig',
Expand All @@ -29,7 +28,6 @@ export const KNOWN_NAMESPACES = [
'inAppMessaging',
'firestore',
'functions',
'iid',
'indexing',
'storage',
'dynamicLinks',
Expand Down
46 changes: 46 additions & 0 deletions packages/storage/__tests__/storage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import storage, { firebase } from '../lib';

describe('Storage', function () {
describe('namespace', function () {
it('accessible from firebase.app()', function () {
const app = firebase.app();
expect(app.storage).toBeDefined();
expect(app.storage().useEmulator).toBeDefined();
});
});

describe('useEmulator()', function () {
it('useEmulator requires a string host', function () {
// @ts-ignore because we pass an invalid argument...
expect(() => storage().useEmulator()).toThrow(
'firebase.storage().useEmulator() takes a non-empty host',
);
expect(() => storage().useEmulator('', -1)).toThrow(
'firebase.storage().useEmulator() takes a non-empty host',
);
// @ts-ignore because we pass an invalid argument...
expect(() => storage().useEmulator(123)).toThrow(
'firebase.storage().useEmulator() takes a non-empty host',
);
});

it('useEmulator requires a host and port', function () {
expect(() => storage().useEmulator('', 9000)).toThrow(
'firebase.storage().useEmulator() takes a non-empty host and port',
);
// No port
// @ts-ignore because we pass an invalid argument...
expect(() => storage().useEmulator('localhost')).toThrow(
'firebase.storage().useEmulator() takes a non-empty host and port',
);
});

it('useEmulator -> remaps Android loopback to host', function () {
const foo = storage().useEmulator('localhost', 9000);
expect(foo).toEqual(['10.0.2.2', 9000]);

const bar = storage().useEmulator('127.0.0.1', 9000);
expect(bar).toEqual(['10.0.2.2', 9000]);
});
});
});
3 changes: 0 additions & 3 deletions packages/storage/android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,4 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- TODO(salakar) Not sure if this should be part of the package manifest or leave to users app manifest code? -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,17 @@ public void setMaxUploadRetryTime(String appName, double milliseconds, Promise p
promise.resolve(null);
}

/**
* @link https://firebase.google.com/docs/reference/js/firebase.storage.Storage#useEmulator
*/
@ReactMethod
public void useEmulator(String appName, String host, int port, Promise promise) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp);
firebaseStorage.useEmulator(host, port);
promise.resolve(null);
}

/**
* @link https://firebase.google.com/docs/reference/js/firebase.storage.Reference#writeToFile
*/
Expand Down
Loading