With hooks support coming in React Native version 0.59.x and with React Native Firebase v6 development well under way; one thing we wanted to add is a collection of officially supported hooks for React Native Firebase.
We've had a placeholder package in v6 for some months now and we'd like to start adding hooks to it.
I'd like to propose the following package structure for the hooks:
// each Firebase service has its own hooks namespaced
// e.g. database hooks
import { useSomeDatabaseHook } from '@react-native-firebase/hooks/database';
// e.g. storage hooks
import { useSomeStorageHook } from '@react-native-firebase/hooks/storage';
The purpose of this issue is to open up discussions for what hooks people would like to see and also open this up to anyone interested in contributing to them.
If you have a proposal/suggestion for a hook please follow the below template when replying:
Firebase Service: e.g. auth
Description: e.g. subscribe to user auth state
Example Usage:
import { useStorageHook } from '@react-native-firebase/hooks/storage';
async function myHookExample() {
// ...
// ...
}
Some required reading I'd suggest would be https://github.com/CSFrequency/react-firebase-hooks and (slightly shaking my own branch): https://medium.com/@sampsonjoliver/firebase-meet-react-hooks-db589c625106
I'm just about to adopt RNF into our mobile app at work, I'd be happy to provide some contributions for Hooks as I go, but unfortunately I won't be touching Database, Auth or Firestore too much so if someone else would like to champion those that'd be fab.
@sampsonjoliver the ones on your blog post look great and useful 馃憣
I think it'd be good if the hooks are specific to React Native Firebase only due to the many additional modules that are provided natively that don't exist on the Web SDK, I think trying to cater to both and their differences might be more hassle than it's worth, that's just my opinion on it though 馃檲
I'd be happy to provide some contributions for Hooks as I go, but unfortunately I won't be touching Database, Auth or Firestore too much so if someone else would like to champion those that'd be fab.
That's absolutely fine, we'd like to gradually add in hooks over time, no requirements to have hooks for all the things immediately :) there will be 21 Firebase services in React Native Firebase - which services did you have in mind?
@Salakar I absolutely agree, RNF hooks should be specific to the RNF ecosystem for the best Developer Experience, rather than generalised to the React web space. I only link those two articles as a starting point :)
I expect to be working with Remote Config and Cloud Messaging in my project, so will try and focus efforts there. I think the former could be a great candidate for Hooks, but probably not so much the latter.
Before getting started on this it'd be good to lay down some core principles on how the hooks handle things such as multiple Firebase instances (the above repo/example) seems like a long winded process passing the entire app instance down each time you call a hook, e.g:
const { initialising, user } = useAuthState(firebase.auth());
I may be missing something, but I don't see why the instance has to be passed down each time when the firebase (or react-native-firebase) has access to them by name. Need to investigate this though.
Auth, Database, Firestore and Messaging probably need the most thought before diving in, the others should be fairly straightforward 馃憤
@Ehesp _I_ might be missing something, how do you get access to the firebase instance by name?
I know firebase allows initialising multiple instances to different projects via
const primary = firebase.initializeApp(primaryConfig);
const secondary = firebase.initializeApp(secondaryConfig, 'secondary');
but afaik you then need to hold and pass those references, as calling initializeApp again throws an error?
@sampsonjoliver firebase.apps : https://rnfirebase.io/docs/v5.x.x/core/reference/core#apps - returns an array of all apps; given that we internally store this as a map we could potentially expose functionality to get the app by name without iterating the array.
One of the benefits of using a name instead of an app instance is that we can ensure the app still exists and has not been deleted since the instance of the class was created. The second is that if you don't pass an app name at all then we could default to the [DEFAULT] app like the rest of the firebase APIs do; less args
Some ideas:
The use<Module> hook which returns the app instance and additional helpers... something like:
import useAuth from '@react-native-firebase/hooks/auth';
function App() {
const [auth, state] = useAuth('app2');
const { initialising, user } = state;
...
// initialising (waiting for onAuthStateChange)
if (initialising) return null;
...
// no user (signed-out)
function signIn() {
return auth().signInWithEmailAndPassword(...)
.catch(e => ...);
}
return <Button onPress={() => signIn()}>Sign In</Button>;
...
// With user/signed-in
return <Button onPress={() => auth().signOut()}>Sign Out</Button>;
}
But also provide hooks with more specific use cases:
import { useAuthState } from '@react-native-firebase/hooks/auth';
function App() {
const { initialising, user } = useAuthState('app2');
// similar logic to above
}
Hmm, I would suggest we should _mostly_ focus on those specific cases rather than the general ones - else there is little to separate the hook from doing the same thing as just getting the firebase.app and calling app.auth().
The more internal state we can capture inside of the hook, the better! Great start to get discussion going though.
The more internal state we can capture inside of the hook, the better! Great start to get discussion going though.
Definitely, I think a key point of having hooks for React Native Firebase is to reduce the code required to use a feature, the more of this 'boilerplate code' that's captured internally inside a hook the better. There are some cases though where basic hooks are still nice to have even if they are simple; keeps things familiar I think.
I'll send up some hook proposals for Storage in the next couple of weeks.
Hello 馃憢, this issue has been automatically marked as stale because it has not had activity for quite some time. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. Thank you for your contributions.
Going to park this one until after the v6 release - will close for now.
Most helpful comment
@sampsonjoliver
firebase.apps: https://rnfirebase.io/docs/v5.x.x/core/reference/core#apps - returns an array of all apps; given that we internally store this as a map we could potentially expose functionality to get the app by name without iterating the array.One of the benefits of using a name instead of an app instance is that we can ensure the app still exists and has not been deleted since the instance of the class was created. The second is that if you don't pass an app name at all then we could default to the
[DEFAULT]app like the rest of the firebase APIs do; less args