Skip to content

Add Firestore ReactNative build #3198

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 3 commits into from
Jun 11, 2020
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
3 changes: 3 additions & 0 deletions packages/firebase/src/index.rn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { name, version } from '../package.json';

import '../auth';
import '../database';
// TODO(b/158625454): Storage doesn't actually work by default in RN (it uses
// `atob`). We should provide a RN build that works out of the box.
import '../storage';
import '../firestore';

firebase.registerVersion(name, version, 'rn');

Expand Down
2 changes: 1 addition & 1 deletion packages/firestore/index.node.memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function registerFirestore(instance: FirebaseNamespace): void {
instance,
(app, auth) => new Firestore(app, auth, new MemoryComponentProvider())
);
instance.registerVersion(name, version);
instance.registerVersion(name, version, 'node');
}

registerFirestore(firebase);
42 changes: 42 additions & 0 deletions packages/firestore/index.rn.memory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import firebase from '@firebase/app';
import { FirebaseNamespace } from '@firebase/app-types';

import { Firestore } from './src/api/database';
import { MemoryComponentProvider } from './src/core/component_provider';
import { configureForFirebase } from './src/platform/config';

import './register-module';
import './src/platform_rn/rn_init';

import { name, version } from './package.json';

/**
* Registers the memory-only Firestore build for ReactNative with the components
* framework.
*/
export function registerFirestore(instance: FirebaseNamespace): void {
configureForFirebase(
instance,
(app, auth) => new Firestore(app, auth, new MemoryComponentProvider())
);
instance.registerVersion(name, version, 'rn');
}

registerFirestore(firebase);
41 changes: 41 additions & 0 deletions packages/firestore/index.rn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import firebase from '@firebase/app';
import { FirebaseNamespace } from '@firebase/app-types';

import { Firestore } from './src/api/database';
import { IndexedDbComponentProvider } from './src/core/component_provider';
import { configureForFirebase } from './src/platform/config';

import './register-module';
import './src/platform_rn/rn_init';

import { name, version } from './package.json';

/**
* Registers the main Firestore ReactNative build with the components framework.
* Persistence can be enabled via `firebase.firestore().enablePersistence()`.
*/
export function registerFirestore(instance: FirebaseNamespace): void {
configureForFirebase(
instance,
(app, auth) => new Firestore(app, auth, new IndexedDbComponentProvider())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RN doesn't support indexeddb, so we should use MemoryComponentProvider here. Probably just remove this file, and point react-native in the root package.json to the memory build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some users that are using our IndexedDb Shim support. I am not sure if we should break them in this PR. FWIW, our main Node build also ships with IndexedDb support.

);
instance.registerVersion(name, version, 'rn');
}

registerFirestore(firebase);
1 change: 1 addition & 0 deletions packages/firestore/memory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "A memory-only build of the Cloud Firestore JS SDK.",
"main": "../dist/index.memory.node.cjs.js",
"main-esm2017": "../dist/index.memory.node.esm2017.js",
"react-native": "../dist/index.memory.rn.esm2017.js",
"browser": "../dist/index.memory.cjs.js",
"module": "../dist/index.memory.esm.js",
"esm2017": "../dist/index.memory.esm2017.js",
Expand Down
1 change: 1 addition & 0 deletions packages/firestore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"main": "dist/index.node.cjs.js",
"main-esm2017": "dist/index.node.esm2017.js",
"react-native": "dist/index.rn.esm2017.js",
"browser": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"esm2017": "dist/index.esm2017.js",
Expand Down
27 changes: 26 additions & 1 deletion packages/firestore/rollup.config.es2017.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,31 @@ const browserBuilds = [
}
];

const reactNativeBuilds = [
// Persistence build
{
input: 'index.rn.ts',
output: {
file: pkg['react-native'],
format: 'es',
sourcemap: true
},
plugins: browserBuildPlugins,
external: resolveBrowserExterns
},
// Memory-only build
{
input: 'index.rn.memory.ts',
output: {
file: path.resolve('./memory', memoryPkg['react-native']),
format: 'es',
sourcemap: true
},
plugins: browserBuildPlugins,
external: resolveBrowserExterns
}
];

// MARK: Node builds

const nodeBuildPlugins = [
Expand Down Expand Up @@ -145,4 +170,4 @@ const nodeBuilds = [
}
];

export default [...browserBuilds, ...nodeBuilds];
export default [...browserBuilds, ...reactNativeBuilds, ...nodeBuilds];
11 changes: 4 additions & 7 deletions packages/firestore/src/platform_browser/browser_platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,18 @@ import { DatabaseId, DatabaseInfo } from '../core/database_info';
import { Platform } from '../platform/platform';
import { Connection } from '../remote/connection';
import { JsonProtoSerializer } from '../remote/serializer';
import { ConnectivityMonitor } from './../remote/connectivity_monitor';
import { ConnectivityMonitor } from '../remote/connectivity_monitor';

import { NoopConnectivityMonitor } from '../remote/connectivity_monitor_noop';
import { BrowserConnectivityMonitor } from './browser_connectivity_monitor';
import { WebChannelConnection } from './webchannel_connection';
import { debugAssert } from '../util/assert';

// Implements the Platform API for browsers and some browser-like environments
// (including ReactNative).
// (including ReactNative, which has its own ReactNativePlatform that extends
// from this class).
export class BrowserPlatform implements Platform {
readonly base64Available: boolean;

constructor() {
this.base64Available = typeof atob !== 'undefined';
}
readonly base64Available = typeof atob !== 'undefined';

get document(): Document | null {
// `document` is not always available, e.g. in ReactNative and WebWorkers.
Expand Down
28 changes: 28 additions & 0 deletions packages/firestore/src/platform_rn/rn_init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { PlatformSupport } from '../platform/platform';
import { ReactNativePlatform } from './rn_platform';

/**
* This code needs to run before Firestore is used. This can be achieved in
* several ways:
* 1) Through the JSCompiler compiling this code and then (automatically)
* executing it before exporting the Firestore symbols.
* 2) Through importing this module first in a Firestore main module
*/
PlatformSupport.setPlatform(new ReactNativePlatform());
36 changes: 36 additions & 0 deletions packages/firestore/src/platform_rn/rn_platform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { BrowserPlatform } from '../platform_browser/browser_platform';
import { base64 } from '@firebase/util';

// Implements the Platform API for ReactNative.
export class ReactNativePlatform extends BrowserPlatform {
readonly base64Available = true;

atob(encoded: string): string {
// WebSafe uses a different URL-encoding safe alphabet that doesn't match
// the encoding used on the backend.
return base64.decodeString(encoded, /* webSafe =*/ false);
}

btoa(raw: string): string {
// WebSafe uses a different URL-encoding safe alphabet that doesn't match
// the encoding used on the backend.
return base64.encodeString(raw, /* webSafe =*/ false);
}
}