Skip to content

Commit fe959bb

Browse files
SalakarEhesp
authored andcommitted
[v6] Implement Realtime Database (#2195)
* [database] recreate database branch based off of #2185 * [database] cleanup linting issues * [database] enable tests * [database] add to tests deps
1 parent da9c320 commit fe959bb

File tree

126 files changed

+12045
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+12045
-46
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.invertase.firebase.common;
2+
3+
/*
4+
* Copyright (c) 2016-present Invertase Limited & Contributors
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this library except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
import android.content.Context;
21+
import android.content.SharedPreferences;
22+
23+
24+
import io.invertase.firebase.app.ReactNativeFirebaseApp;
25+
26+
public class UniversalFirebasePreferences {
27+
private static final String PREFERENCES_FILE = "io.invertase.firebase";
28+
private static UniversalFirebasePreferences sharedInstance = new UniversalFirebasePreferences();
29+
private SharedPreferences preferences;
30+
31+
public static UniversalFirebasePreferences getSharedInstance() {
32+
return sharedInstance;
33+
}
34+
35+
public boolean contains(String key) {
36+
return getPreferences().contains(key);
37+
}
38+
39+
public void setBooleanValue(String key, boolean value) {
40+
getPreferences().edit().putBoolean(key, value).apply();
41+
}
42+
43+
public boolean getBooleanValue(String key, boolean defaultValue) {
44+
return getPreferences().getBoolean(key, defaultValue);
45+
}
46+
47+
public void setLongValue(String key, long value) {
48+
getPreferences().edit().putLong(key, value).apply();
49+
}
50+
51+
public long getLongValue(String key, long defaultValue) {
52+
return getPreferences().getLong(key, defaultValue);
53+
}
54+
55+
public void setStringValue(String key, String value) {
56+
getPreferences().edit().putString(key, value).apply();
57+
}
58+
59+
public String getStringValue(String key, String defaultValue) {
60+
return getPreferences().getString(key, defaultValue);
61+
}
62+
63+
public void clearAll() {
64+
getPreferences().edit().clear().apply();
65+
}
66+
67+
private SharedPreferences getPreferences() {
68+
if (preferences == null) {
69+
preferences = ReactNativeFirebaseApp
70+
.getApplicationContext()
71+
.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
72+
}
73+
return preferences;
74+
}
75+
}

packages/app/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ public static void initializeSecondaryApp(String name) {
3939
FirebaseOptions options = FirebaseOptions.fromResource(applicationContext);
4040
FirebaseApp.initializeApp(applicationContext, options, name);
4141
}
42+
43+
public static void initializeSecondaryApp(String name, Context applicationContext) {
44+
FirebaseOptions options = FirebaseOptions.fromResource(applicationContext);
45+
FirebaseApp.initializeApp(applicationContext, options, name);
46+
}
4247
}

packages/app/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,23 @@
2525
import java.util.ArrayList;
2626
import java.util.Collections;
2727
import java.util.List;
28+
import javax.annotation.Nonnull;
2829

2930
@SuppressWarnings("unused")
3031
public class ReactNativeFirebaseAppPackage implements ReactPackage {
32+
@Nonnull
3133
@Override
32-
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
34+
public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
35+
if (ReactNativeFirebaseApp.getApplicationContext() == null) {
36+
ReactNativeFirebaseApp.setApplicationContext(reactContext.getApplicationContext());
37+
}
3338
List<NativeModule> modules = new ArrayList<>();
3439
modules.add(new ReactNativeFirebaseAppModule(reactContext));
3540
return modules;
3641
}
3742

3843
@Override
39-
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
44+
public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
4045
return Collections.emptyList();
4146
}
4247
}

packages/app/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,20 @@ public static WritableMap mapPutValue(String key, @Nullable Object value, Writab
176176
return map;
177177
}
178178

179+
// TODO Remove me - also in SharedUtils
179180
public static WritableMap readableMapToWritableMap(ReadableMap map) {
180181
WritableMap writableMap = Arguments.createMap();
181182
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/WritableNativeMap.java#L54
182183
writableMap.merge(map);
183184
return writableMap;
184185
}
185186

186-
public static Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) {
187+
public static Map<String, Object> toHashMap(ReadableMap readableMap) {
187188
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java#L216
188189
return readableMap.toHashMap();
189190
}
190191

191-
public static List<Object> recursivelyDeconstructReadableArray(ReadableArray readableArray) {
192+
public static List<Object> toArrayList(ReadableArray readableArray) {
192193
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java#L175
193194
return readableArray.toArrayList();
194195
}

packages/app/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ public boolean getBooleanValue(String key, boolean defaultValue) {
4848
return getPreferences().getBoolean(key, defaultValue);
4949
}
5050

51+
public void setLongValue(String key, long value) {
52+
getPreferences().edit().putLong(key, value).apply();
53+
}
54+
55+
public long getLongValue(String key, long defaultValue) {
56+
return getPreferences().getLong(key, defaultValue);
57+
}
58+
5159
public void setStringValue(String key, String value) {
5260
getPreferences().edit().putString(key, value).apply();
5361
}

packages/app/ios/RNFBApp/RNFBPreferences.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@
2525

2626
- (void)setBooleanValue:(NSString *)key boolValue:(BOOL)boolValue;
2727

28+
- (void)setIntegerValue:(NSString *)key integerValue:(NSInteger *)integerValue;
29+
2830
- (void)setStringValue:(NSString *)key stringValue:(NSString *)stringValue;
2931

3032
- (NSString *)getStringValue:(NSString *)key defaultValue:(NSString *)defaultValue;
3133

34+
- (NSInteger *)getIntegerValue:(NSString *)key defaultValue:(NSInteger *)defaultValue;
35+
3236
- (NSDictionary *)getAll;
3337

3438
- (void)clearAll;

packages/app/ios/RNFBApp/RNFBPreferences.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ - (void)setBooleanValue:(NSString *)key boolValue:(BOOL)boolValue {
5555
[_userDefaults synchronize];
5656
}
5757

58+
- (void)setIntegerValue:(NSString *)key integerValue:(NSInteger *)integerValue {
59+
[_userDefaults setInteger:(NSInteger) integerValue forKey:key];
60+
[_userDefaults synchronize];
61+
}
62+
63+
- (NSInteger *)getIntegerValue:(NSString *)key defaultValue:(NSInteger *)defaultValue {
64+
if ([_userDefaults objectForKey:key] != nil) return defaultValue;
65+
return (NSInteger *) [_userDefaults integerForKey:key];
66+
}
67+
5868
- (NSString *)getStringValue:(NSString *)key defaultValue:(NSString *)defaultValue {
5969
if ([_userDefaults objectForKey:key] != nil) return defaultValue;
6070
return [_userDefaults stringForKey:key];

packages/app/lib/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*/
1717

18-
import {ReactNativeFirebaseNamespace} from "@react-native-firebase/app-types";
18+
import { ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types';
1919

2020
/**
2121
* @firebase firebase

packages/app/lib/internal/FirebaseModule.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export default class FirebaseModule {
4242
return SharedEventEmitter;
4343
}
4444

45+
// TODO Handle custom url or region?
4546
eventNameForApp(...args) {
4647
return `${this.app.name}-${args.join('-')}`;
4748
}

packages/common/lib/Base64.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818

1919
import binaryToBase64 from 'react-native/Libraries/Utilities/binaryToBase64';
20-
import promiseDefer from './promiseDefer';
20+
import { promiseDefer } from './promise';
2121

2222
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
2323

packages/common/lib/deeps.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { isObject } from './validate';
2+
3+
/**
4+
* Deep get a value from an object.
5+
* @website https://github.com/Salakar/deeps
6+
* @param object
7+
* @param path
8+
* @param joiner
9+
* @returns {*}
10+
*/
11+
// eslint-disable-next-line import/prefer-default-export
12+
export function deepGet(object, path, joiner = '/') {
13+
if (!isObject(object) && !Array.isArray(object)) return undefined;
14+
const keys = path.split(joiner);
15+
16+
let i = 0;
17+
let tmp = object;
18+
const len = keys.length;
19+
20+
while (i < len) {
21+
const key = keys[i++];
22+
if (!tmp || !Object.hasOwnProperty.call(tmp, key)) return undefined;
23+
tmp = tmp[key];
24+
}
25+
26+
return tmp;
27+
}

packages/common/lib/id.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
2+
3+
const AUTO_ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
4+
5+
// timestamp of last push, used to prevent local collisions if you push twice in one ms.
6+
let lastPushTime = 0;
7+
8+
// we generate 72-bits of randomness which get turned into 12 characters and appended to the
9+
// timestamp to prevent collisions with other clients. We store the last characters we
10+
// generated because in the event of a collision, we'll use those same characters except
11+
// "incremented" by one.
12+
const lastRandChars = [];
13+
14+
/**
15+
* Generate a firebase id - for use with ref().push(val, cb) - e.g. -KXMr7k2tXUFQqiaZRY4'
16+
* @param serverTimeOffset - pass in server time offset from native side
17+
* @returns {string}
18+
*/
19+
export function generateDatabaseId(serverTimeOffset = 0): string {
20+
const timeStampChars = new Array(8);
21+
let now = new Date().getTime() + serverTimeOffset;
22+
const duplicateTime = now === lastPushTime;
23+
24+
lastPushTime = now;
25+
26+
for (let i = 7; i >= 0; i -= 1) {
27+
timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
28+
now = Math.floor(now / 64);
29+
}
30+
31+
if (now !== 0) {
32+
throw new Error('We should have converted the entire timestamp.');
33+
}
34+
35+
let id = timeStampChars.join('');
36+
37+
if (!duplicateTime) {
38+
for (let i = 0; i < 12; i += 1) {
39+
lastRandChars[i] = Math.floor(Math.random() * 64);
40+
}
41+
} else {
42+
// if the timestamp hasn't changed since last push,
43+
// use the same random number, but increment it by 1.
44+
let i;
45+
for (i = 11; i >= 0 && lastRandChars[i] === 63; i -= 1) {
46+
lastRandChars[i] = 0;
47+
}
48+
49+
lastRandChars[i] += 1;
50+
}
51+
52+
for (let i = 0; i < 12; i++) {
53+
id += PUSH_CHARS.charAt(lastRandChars[i]);
54+
}
55+
56+
if (id.length !== 20) throw new Error('Length should be 20.');
57+
58+
return id;
59+
}
60+
61+
/**
62+
* Generate a firestore auto id for use with collection/document .add()
63+
* @return {string}
64+
*/
65+
export function generateFirestoreId(): string {
66+
let autoId = '';
67+
68+
for (let i = 0; i < 20; i++) {
69+
autoId += AUTO_ID_CHARS.charAt(Math.floor(Math.random() * AUTO_ID_CHARS.length));
70+
}
71+
return autoId;
72+
}

packages/common/lib/index.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import { Platform } from 'react-native';
1818
import { isString } from './validate';
1919
import Base64 from './Base64';
2020

21+
export * from './id';
2122
export * from './path';
2223
export * from './validate';
24+
export * from './promise';
2325
export Base64 from './Base64';
24-
export promiseDefer from './promiseDefer';
2526
export ReferenceBase from './ReferenceBase';
2627

2728
export function getDataUrlParts(dataUrlString) {
@@ -74,3 +75,19 @@ export function stripTrailingSlash(string) {
7475
export const isIOS = Platform.OS === 'ios';
7576

7677
export const isAndroid = Platform.OS === 'android';
78+
79+
export function tryJSONParse(string) {
80+
try {
81+
return string && JSON.parse(string);
82+
} catch (jsonError) {
83+
return string;
84+
}
85+
}
86+
87+
export function tryJSONStringify(data: mixed): string | null {
88+
try {
89+
return JSON.stringify(data);
90+
} catch (jsonError) {
91+
return null;
92+
}
93+
}

0 commit comments

Comments
 (0)