Skip to content

Commit

Permalink
fix(other): add api for persistence via Async Storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Salakar committed Jul 18, 2024
1 parent 2c787c2 commit 030eea9
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
38 changes: 38 additions & 0 deletions packages/app/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,36 @@ export namespace ReactNativeFirebase {
utils(): Utils.Module;
}

/**
* Interface for a supplied `AsyncStorage`.
*/
export interface ReactNativeAsyncStorage {
/**
* Persist an item in storage.
*
* @param key - storage key.
* @param value - storage value.
*/
// eslint-disable-next-line @typescript-eslint/ban-types
setItem: Function;
/**
* Retrieve an item from storage.
*
* @param key - storage key.
*/
// eslint-disable-next-line @typescript-eslint/ban-types
getItem: Function;
/**
* Remove an item from storage.
*
* @param key - storage key.
*/
// eslint-disable-next-line @typescript-eslint/ban-types
removeItem: Function;

[key: string]: any;
}

export interface Module {
/**
* Create (and initialize) a FirebaseApp.
Expand Down Expand Up @@ -201,6 +231,14 @@ export namespace ReactNativeFirebase {
*/
setLogLevel(logLevel: LogLevelString): void;

/**
* The `AsyncStorage` implementation to use for persisting data on 'Other' platforms.
* If not specified, in memory persistence is used.
*
* This is required if you want to persist things like Auth sessions, Analytics device IDs, etc.
*/
setReactNativeAsyncStorage(asyncStorage: ReactNativeAsyncStorage): void;

/**
* A (read-only) array of all the initialized Apps.
*/
Expand Down
47 changes: 47 additions & 0 deletions packages/app/lib/internal/asyncStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export const memoryStorage = new Map();

export const prefix = '@react-native-firebase:';

const asyncStorageMemory = {
setItem(key, value) {
memoryStorage.set(key, value);
return Promise.resolve();
},
getItem(key) {
const hasValue = memoryStorage.has(key);
if (hasValue) {
return Promise.resolve(memoryStorage.get(key));
}
return Promise.resolve(null);
},
removeItem: function (key) {
memoryStorage.delete(key);
return Promise.resolve();
},
};

let asyncStorage = asyncStorageMemory;

export async function getReactNativeAsyncStorageInternal() {
return asyncStorage;
}

export function setReactNativeAsyncStorageInternal(asyncStorageInstance) {
asyncStorage = asyncStorageInstance || asyncStorageMemory;
}

export function isMemoryStorage() {
return asyncStorage === asyncStorageMemory;
}

export async function setItem(key, value) {
return await asyncStorage.setItem(prefix + key, value);
}

export async function getItem(key) {
return await asyncStorage.getItem(prefix + key);
}

export async function removeItem(key) {
return await asyncStorage.removeItem(prefix + key);
}
32 changes: 30 additions & 2 deletions packages/app/lib/internal/registry/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import {
isOther,
isNull,
isObject,
isFunction,
isString,
isUndefined,
} from '@react-native-firebase/app/lib/common';
import FirebaseApp from '../../FirebaseApp';
import { DEFAULT_APP_NAME } from '../constants';
import { setReactNativeAsyncStorageInternal } from '../asyncStorage';
import { getAppModule } from './nativeModule';

const APP_REGISTRY = {};
Expand Down Expand Up @@ -172,15 +174,15 @@ export function initializeApp(options = {}, configOrName) {
);
}

const app = new FirebaseApp(options, { name }, false, deleteApp.bind(null, name, true));
const app = new FirebaseApp(options, appConfig, false, deleteApp.bind(null, name, true));

// Note these initialization actions with side effects are performed prior to knowledge of
// successful initialization in the native code. Native code *may* throw an error.
APP_REGISTRY[name] = app;
onAppCreateFn(APP_REGISTRY[name]);

return getAppModule()
.initializeApp(options, { name })
.initializeApp(options, appConfig)
.then(() => {
app._initialized = true;
return app;
Expand All @@ -207,6 +209,32 @@ export function setLogLevel(logLevel) {
}
}

export function setReactNativeAsyncStorage(asyncStorage) {
if (!isObject(asyncStorage)) {
throw new Error("firebase.setReactNativeAsyncStorage(*) 'asyncStorage' must be an object.");
}

if (!isFunction(asyncStorage.setItem)) {
throw new Error(
"firebase.setReactNativeAsyncStorage(*) 'asyncStorage.setItem' must be a function.",
);
}

if (!isFunction(asyncStorage.getItem)) {
throw new Error(
"firebase.setReactNativeAsyncStorage(*) 'asyncStorage.getItem' must be a function.",
);
}

if (!isFunction(asyncStorage.removeItem)) {
throw new Error(
"firebase.setReactNativeAsyncStorage(*) 'asyncStorage.removeItem' must be a function.",
);
}

setReactNativeAsyncStorageInternal(asyncStorage);
}

/**
*
*/
Expand Down
2 changes: 2 additions & 0 deletions packages/app/lib/internal/registry/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getApps,
initializeApp,
setLogLevel,
setReactNativeAsyncStorage,
setOnAppCreate,
setOnAppDestroy,
} from './app';
Expand Down Expand Up @@ -241,6 +242,7 @@ export function firebaseAppModuleProxy(app, moduleNamespace) {
export function createFirebaseRoot() {
FIREBASE_ROOT = {
initializeApp,
setReactNativeAsyncStorage,
get app() {
return getApp;
},
Expand Down

0 comments on commit 030eea9

Please sign in to comment.