Skip to content

Commit c3a82f6

Browse files
scottcrossensam-gc
authored andcommitted
Add react native persistence class (#2955)
Added React Native persistence class
1 parent 30b7dab commit c3a82f6

File tree

8 files changed

+188
-7
lines changed

8 files changed

+188
-7
lines changed

packages-exp/auth-compat-exp/index.rn.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* just use index.ts
2323
*/
2424

25-
import { testFxn } from './src';
25+
import { AsyncStorage } from 'react-native';
26+
import { ReactNativePersistence } from '@firebase/auth-exp/src/core/persistence/react_native';
2627

27-
testFxn();
28+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
29+
const reactNativeLocalPersistence = new ReactNativePersistence(AsyncStorage);

packages-exp/auth-compat-exp/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
},
2727
"peerDependencies": {
2828
"@firebase/app-exp": "0.x",
29-
"@firebase/app-types-exp": "0.x"
29+
"@firebase/app-types-exp": "0.x",
30+
"@firebase/auth-exp": "0.x",
31+
"@firebase/auth-types-exp": "0.x"
3032
},
3133
"dependencies": {
3234
"tslib": "1.11.1"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* Basic stub for what is expected from the package 'react-native'.
20+
*
21+
* This should be a subset `@types/react-native` which cannot be installed
22+
* because it has conflicting definitions with typescript/dom. If included in
23+
* deps, yarn will attempt to install this in the root directory of the
24+
* monolithic repository which will then be included in the base `tsconfig.json`
25+
* via `typeroots` and then break every other package in this repo.
26+
*/
27+
28+
declare module 'react-native' {
29+
interface ReactNativeAsyncStorage {
30+
setItem(key: string, value: string): Promise<void>;
31+
getItem(key: string): Promise<string | null>;
32+
removeItem(key: string): Promise<void>;
33+
}
34+
export const AsyncStorage: ReactNativeAsyncStorage;
35+
}

packages-exp/auth-compat-exp/rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const es5Builds = [
5555
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
5656
},
5757
/**
58-
* App React Native Builds
58+
* React Native Builds
5959
*/
6060
{
6161
input: 'index.rn.ts',

packages-exp/auth-exp/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
},
2727
"peerDependencies": {
2828
"@firebase/app-exp": "0.x",
29-
"@firebase/app-types-exp": "0.x"
29+
"@firebase/app-types-exp": "0.x",
30+
"@firebase/auth-types-exp": "0.x"
3031
},
3132
"dependencies": {
3233
"@firebase/logger": "^0.2.2",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
20+
import { testUser } from '../../../test/mock_auth';
21+
import { PersistedBlob, PersistenceType } from './';
22+
import { ReactNativePersistence } from './react_native';
23+
import { ReactNativeAsyncStorage } from '@firebase/auth-types-exp';
24+
25+
/**
26+
* Wraps in-memory storage with the react native AsyncStorage API.
27+
*/
28+
class FakeAsyncStorage implements ReactNativeAsyncStorage {
29+
storage: {
30+
[key: string]: string;
31+
} = {};
32+
33+
async getItem(key: string): Promise<string | null> {
34+
const value = this.storage[key];
35+
return value ?? null;
36+
}
37+
async removeItem(key: string): Promise<void> {
38+
delete this.storage[key];
39+
}
40+
async setItem(key: string, value: string): Promise<void> {
41+
this.storage[key] = value;
42+
}
43+
clear(): void {
44+
this.storage = {};
45+
}
46+
}
47+
48+
describe('core/persistence/react', () => {
49+
const fakeAsyncStorage = new FakeAsyncStorage();
50+
const persistence = new ReactNativePersistence(fakeAsyncStorage);
51+
52+
beforeEach(() => {
53+
fakeAsyncStorage.clear();
54+
});
55+
56+
it('should work with persistence type', async () => {
57+
const key = 'my-super-special-persistence-type';
58+
const value = PersistenceType.LOCAL;
59+
expect(await persistence.get(key)).to.be.null;
60+
await persistence.set(key, value);
61+
expect(await persistence.get(key)).to.be.eq(value);
62+
expect(await persistence.get('other-key')).to.be.null;
63+
await persistence.remove(key);
64+
expect(await persistence.get(key)).to.be.null;
65+
});
66+
67+
it('should return persistedblob from user', async () => {
68+
const key = 'my-super-special-user';
69+
const value = testUser('some-uid');
70+
71+
expect(await persistence.get(key)).to.be.null;
72+
await persistence.set(key, value.toPlainObject());
73+
const out = await persistence.get<PersistedBlob>(key);
74+
expect(out!['uid']).to.eql(value.uid);
75+
await persistence.remove(key);
76+
expect(await persistence.get(key)).to.be.null;
77+
});
78+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import {
19+
Persistence,
20+
PersistenceType,
21+
PersistenceValue,
22+
STORAGE_AVAILABLE_KEY
23+
} from './';
24+
import {ReactNativeAsyncStorage} from '@firebase/auth-types-exp';
25+
26+
/**
27+
* Persistence class that wraps AsyncStorage imported from `react-native` or `@react-native-community/async-storage`.
28+
*/
29+
export class ReactNativePersistence implements Persistence {
30+
readonly type: PersistenceType = PersistenceType.LOCAL;
31+
32+
constructor(private readonly storage: ReactNativeAsyncStorage) {}
33+
34+
async isAvailable(): Promise<boolean> {
35+
try {
36+
if (!this.storage) {
37+
return false;
38+
}
39+
await this.storage.setItem(STORAGE_AVAILABLE_KEY, '1');
40+
await this.storage.removeItem(STORAGE_AVAILABLE_KEY);
41+
return true;
42+
} catch {
43+
return false;
44+
}
45+
}
46+
47+
async set(key: string, value: PersistenceValue): Promise<void> {
48+
await this.storage.setItem(key, JSON.stringify(value));
49+
}
50+
51+
async get<T extends PersistenceValue>(
52+
key: string
53+
): Promise<T | null> {
54+
const json = await this.storage.getItem(key);
55+
return json ? JSON.parse(json) : null;
56+
}
57+
58+
async remove(key: string): Promise<void> {
59+
await this.storage.removeItem(key);
60+
}
61+
}

packages-exp/auth-types-exp/index.d.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* limitations under the License.
1616
*/
1717

18-
export interface TestType {
19-
prop?: string;
18+
export interface ReactNativeAsyncStorage {
19+
setItem(key: string, value: string): Promise<void>;
20+
getItem(key: string): Promise<string | null>;
21+
removeItem(key: string): Promise<void>;
2022
}

0 commit comments

Comments
 (0)