Skip to content

Commit 5cca81d

Browse files
authored
feat: add reload callback to once, feat: adds inactive request protection to Firestore *Once methods (mirror 201) (#4)
* refactor useCollection, include race condition code * chore(example): add navigaton to add more example test cases * chore(example): add navigaton to add more example test cases * finish refactoring * chore: add *Once example cases * refactor: *Once hooks to use same internal impl * refactor: hooks to use same internal impl * fix: use*Once didn't update when query changed
1 parent fa5dcf5 commit 5cca81d

26 files changed

+824
-256
lines changed

example/App.tsx

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,69 @@
11
import React from 'react';
2-
import { StatusBar } from 'expo-status-bar';
3-
import {
4-
ActivityIndicator,
5-
Button,
6-
StyleSheet,
7-
Text,
8-
View,
9-
} from 'react-native';
10-
import { useCollectionData } from '@skillnation/react-native-firebase-hooks/firestore';
11-
import firestore from '@react-native-firebase/firestore';
2+
import { NavigationContainer } from '@react-navigation/native';
3+
import { createDrawerNavigator } from '@react-navigation/drawer';
4+
import ChangeQuery_useCollectionData from './src/ChangeQuery_useCollectionData';
5+
import { Basic_useDocumentData } from './src/Basic_useDocumentData';
6+
import { Basic_useDocument } from './src/Basic_useDocument';
7+
import { Basic_useDocumentOnce } from './src/Basic_useDocumentOnce';
8+
import { Basic_useDocumentDataOnce } from './src/Basic_useDocumentDataOnce';
9+
import { Basic_useCollection } from './src/Basic_useCollection';
10+
import { Basic_useCollectionData } from './src/Basic_useCollectionData';
11+
import { Basic_useCollectionOnce } from './src/Basic_useCollectionOnce';
12+
import { Basic_useCollectionDataOnce } from './src/Basic_useCollectionDataOnce';
13+
import { ChangeQuery_useDocumentDataOnce } from './src/ChangeQuery_useDocumentDataOnce';
14+
import { ChangeQuery_useDocumentData } from './src/ChangeQuery_useDocumentData';
1215

13-
type Product = {
14-
name: string;
15-
};
16+
const Drawer = createDrawerNavigator();
1617

1718
export default function App() {
18-
const [collectionName, setCollectionName] = React.useState('invalid');
19-
20-
const [products, loading, error] = useCollectionData<Product>(
21-
firestore().collection(collectionName),
22-
{
23-
snapshotListenOptions: { includeMetadataChanges: true },
24-
}
25-
);
26-
27-
console.log({ product: products, loading, error });
2819
return (
29-
<View style={styles.container}>
30-
<Button
31-
title={'Change state impacting firebase loading'}
32-
onPress={() => setCollectionName('products')}
33-
/>
34-
{loading && <ActivityIndicator />}
35-
{error && <Text>{error.message}</Text>}
36-
{products &&
37-
products.length > 0 &&
38-
products.map((product, i) => <Text key={i}>{product.name}</Text>)}
39-
<StatusBar style="auto" />
40-
</View>
20+
<NavigationContainer>
21+
<Drawer.Navigator>
22+
<Drawer.Screen
23+
name={'Basic_useDocumentData'}
24+
component={Basic_useDocumentData}
25+
/>
26+
<Drawer.Screen
27+
name={'Basic_useDocument'}
28+
component={Basic_useDocument}
29+
/>
30+
<Drawer.Screen
31+
name={'Basic_useDocumentOnce'}
32+
component={Basic_useDocumentOnce}
33+
/>
34+
<Drawer.Screen
35+
name={'Basic_useDocumentDataOnce'}
36+
component={Basic_useDocumentDataOnce}
37+
/>
38+
<Drawer.Screen
39+
name={'Basic_useCollectionData'}
40+
component={Basic_useCollectionData}
41+
/>
42+
<Drawer.Screen
43+
name={'Basic_useCollection'}
44+
component={Basic_useCollection}
45+
/>
46+
<Drawer.Screen
47+
name={'Basic_useCollectionOnce'}
48+
component={Basic_useCollectionOnce}
49+
/>
50+
<Drawer.Screen
51+
name={'Basic_useCollectionDataOnce'}
52+
component={Basic_useCollectionDataOnce}
53+
/>
54+
<Drawer.Screen
55+
name={'ChangeQuery_useCData'}
56+
component={ChangeQuery_useCollectionData}
57+
/>
58+
<Drawer.Screen
59+
name={'ChangeQuery_useDData'}
60+
component={ChangeQuery_useDocumentData}
61+
/>
62+
<Drawer.Screen
63+
name={'ChangeQuery_useDDataOnce'}
64+
component={ChangeQuery_useDocumentDataOnce}
65+
/>
66+
</Drawer.Navigator>
67+
</NavigationContainer>
4168
);
4269
}
43-
44-
const styles = StyleSheet.create({
45-
container: {
46-
flex: 1,
47-
backgroundColor: '#fff',
48-
alignItems: 'center',
49-
justifyContent: 'center',
50-
},
51-
});

example/babel.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = function (api) {
1515
},
1616
},
1717
],
18+
'react-native-reanimated/plugin',
1819
],
1920
};
2021
};

example/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'react-native-gesture-handler';
12
import { registerRootComponent } from 'expo';
23

34
import App from './App';

example/ios/Podfile.lock

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,12 @@ PODS:
10461046
- React-jsinspector (0.68.2)
10471047
- React-logger (0.68.2):
10481048
- glog
1049+
- react-native-safe-area-context (4.2.4):
1050+
- RCT-Folly
1051+
- RCTRequired
1052+
- RCTTypeSafety
1053+
- React
1054+
- ReactCommon/turbomodule/core
10491055
- React-perflogger (0.68.2)
10501056
- React-RCTActionSheet (0.68.2):
10511057
- React-Core/RCTActionSheetHeaders (= 0.68.2)
@@ -1130,6 +1136,38 @@ PODS:
11301136
- Firebase/Storage (= 8.15.0)
11311137
- React-Core
11321138
- RNFBApp
1139+
- RNGestureHandler (2.2.1):
1140+
- React-Core
1141+
- RNReanimated (2.8.0):
1142+
- DoubleConversion
1143+
- FBLazyVector
1144+
- FBReactNativeSpec
1145+
- glog
1146+
- RCT-Folly
1147+
- RCTRequired
1148+
- RCTTypeSafety
1149+
- React-callinvoker
1150+
- React-Core
1151+
- React-Core/DevSupport
1152+
- React-Core/RCTWebSocket
1153+
- React-CoreModules
1154+
- React-cxxreact
1155+
- React-jsi
1156+
- React-jsiexecutor
1157+
- React-jsinspector
1158+
- React-RCTActionSheet
1159+
- React-RCTAnimation
1160+
- React-RCTBlob
1161+
- React-RCTImage
1162+
- React-RCTLinking
1163+
- React-RCTNetwork
1164+
- React-RCTSettings
1165+
- React-RCTText
1166+
- ReactCommon/turbomodule/core
1167+
- Yoga
1168+
- RNScreens (3.11.1):
1169+
- React-Core
1170+
- React-RCTImage
11331171
- Yoga (1.14.0)
11341172

11351173
DEPENDENCIES:
@@ -1168,6 +1206,7 @@ DEPENDENCIES:
11681206
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
11691207
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
11701208
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
1209+
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
11711210
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
11721211
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
11731212
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
@@ -1185,6 +1224,9 @@ DEPENDENCIES:
11851224
- "RNFBDatabase (from `../node_modules/@react-native-firebase/database`)"
11861225
- "RNFBFirestore (from `../node_modules/@react-native-firebase/firestore`)"
11871226
- "RNFBStorage (from `../node_modules/@react-native-firebase/storage`)"
1227+
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
1228+
- RNReanimated (from `../node_modules/react-native-reanimated`)
1229+
- RNScreens (from `../node_modules/react-native-screens`)
11881230
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
11891231

11901232
SPEC REPOS:
@@ -1276,6 +1318,8 @@ EXTERNAL SOURCES:
12761318
:path: "../node_modules/react-native/ReactCommon/jsinspector"
12771319
React-logger:
12781320
:path: "../node_modules/react-native/ReactCommon/logger"
1321+
react-native-safe-area-context:
1322+
:path: "../node_modules/react-native-safe-area-context"
12791323
React-perflogger:
12801324
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
12811325
React-RCTActionSheet:
@@ -1310,6 +1354,12 @@ EXTERNAL SOURCES:
13101354
:path: "../node_modules/@react-native-firebase/firestore"
13111355
RNFBStorage:
13121356
:path: "../node_modules/@react-native-firebase/storage"
1357+
RNGestureHandler:
1358+
:path: "../node_modules/react-native-gesture-handler"
1359+
RNReanimated:
1360+
:path: "../node_modules/react-native-reanimated"
1361+
RNScreens:
1362+
:path: "../node_modules/react-native-screens"
13131363
Yoga:
13141364
:path: "../node_modules/react-native/ReactCommon/yoga"
13151365

@@ -1366,6 +1416,7 @@ SPEC CHECKSUMS:
13661416
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
13671417
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
13681418
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
1419+
react-native-safe-area-context: f98b0b16d1546d208fc293b4661e3f81a895afd9
13691420
React-perflogger: a18b4f0bd933b8b24ecf9f3c54f9bf65180f3fe6
13701421
React-RCTActionSheet: 547fe42fdb4b6089598d79f8e1d855d7c23e2162
13711422
React-RCTAnimation: bc9440a1c37b06ae9ebbb532d244f607805c6034
@@ -1383,6 +1434,9 @@ SPEC CHECKSUMS:
13831434
RNFBDatabase: 7390a8b320e6f1ea82ac6ecd6e19c5a76a4397f0
13841435
RNFBFirestore: 70f47946084f6ce68c827c4a770613e0adb46da3
13851436
RNFBStorage: 814adb8c5bf4ff86a0b0641d750a64d6d48d9a75
1437+
RNGestureHandler: 1dc1ea9d4b64f999042afafbaccf5b143f0b2fa2
1438+
RNReanimated: 64573e25e078ae6bec03b891586d50b9ec284393
1439+
RNScreens: 4d83613b50b74ed277026375dc0810893b0c347f
13861440
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
13871441

13881442
PODFILE CHECKSUM: b657b81c5d6b374ca4cb51dd4551700413a55982

example/ios/example/AppDelegate.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#import <Firebase/Firebase.h>
55
#import <Firebase/Firebase.h>
66
#import <Firebase/Firebase.h>
7+
#import <Firebase/Firebase.h>
78

89
#import <React/RCTBridge.h>
910
#import <React/RCTBundleURLProvider.h>

example/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,20 @@
1414
"@react-native-firebase/database": "^14.11.1",
1515
"@react-native-firebase/firestore": "^14.11.1",
1616
"@react-native-firebase/storage": "^14.11.1",
17+
"@react-navigation/drawer": "^6.4.2",
18+
"@react-navigation/native": "^6.0.10",
19+
"@react-navigation/native-stack": "^6.6.2",
1720
"expo": "~45.0.0",
1821
"expo-dev-client": "~1.0.0",
1922
"expo-splash-screen": "~0.15.1",
2023
"expo-status-bar": "~1.3.0",
2124
"react": "17.0.2",
2225
"react-dom": "17.0.2",
2326
"react-native": "0.68.2",
27+
"react-native-gesture-handler": "~2.2.1",
28+
"react-native-reanimated": "~2.8.0",
29+
"react-native-safe-area-context": "4.2.4",
30+
"react-native-screens": "~3.11.1",
2431
"react-native-web": "0.17.7"
2532
},
2633
"devDependencies": {
@@ -30,5 +37,8 @@
3037
"babel-plugin-module-resolver": "^4.1.0",
3138
"typescript": "~4.3.5"
3239
},
40+
"resolutions": {
41+
"@types/react": "^17"
42+
},
3343
"private": true
3444
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import { useCollection } from '@skillnation/react-native-firebase-hooks/firestore';
3+
import { Product } from './types';
4+
import { BasicScreen } from './components/BasicScreen';
5+
import firestore from '@react-native-firebase/firestore';
6+
7+
export const Basic_useCollection: React.FC = () => {
8+
const hookData = useCollection(firestore().collection<Product>('products'));
9+
10+
return (
11+
<BasicScreen
12+
hookData={hookData}
13+
transformData={(d) => ({
14+
size: d.size,
15+
empty: d.empty,
16+
})}
17+
/>
18+
);
19+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from 'react';
2+
import { useCollectionData } from '@skillnation/react-native-firebase-hooks/firestore';
3+
import { Product } from './types';
4+
import { BasicScreen } from './components/BasicScreen';
5+
import firestore from '@react-native-firebase/firestore';
6+
7+
export const Basic_useCollectionData: React.FC = () => {
8+
const hookData = useCollectionData(
9+
firestore().collection<Product>('products')
10+
);
11+
12+
return <BasicScreen hookData={hookData} />;
13+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from 'react';
2+
import type { Product } from './types';
3+
import { BasicScreen } from './components/BasicScreen';
4+
import firestore from '@react-native-firebase/firestore';
5+
import { useCollectionDataOnce } from '@skillnation/react-native-firebase-hooks/firestore';
6+
7+
export const Basic_useCollectionDataOnce: React.FC = () => {
8+
const hookData = useCollectionDataOnce(
9+
firestore().collection<Product>('products')
10+
);
11+
12+
return <BasicScreen hookData={hookData} />;
13+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import type { Product } from './types';
3+
import { BasicScreen } from './components/BasicScreen';
4+
import firestore from '@react-native-firebase/firestore';
5+
import { useCollectionOnce } from '@skillnation/react-native-firebase-hooks/firestore';
6+
7+
export const Basic_useCollectionOnce: React.FC = () => {
8+
const hookData = useCollectionOnce(
9+
firestore().collection<Product>('products')
10+
);
11+
12+
return (
13+
<BasicScreen
14+
hookData={hookData}
15+
transformData={(d) => ({
16+
size: d.size,
17+
empty: d.empty,
18+
})}
19+
/>
20+
);
21+
};

0 commit comments

Comments
 (0)