diff --git a/.gitignore b/.gitignore index 5d31eeb..8bc1a7c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ npm-debug.log # Testing output .nyc_output coverage + +#test files +/example diff --git a/auth/README.md b/auth/README.md index de06f8b..b5c5d3e 100644 --- a/auth/README.md +++ b/auth/README.md @@ -11,6 +11,8 @@ import { useAuthState } from 'react-firebase-hooks/auth'; List of Auth hooks: - [useAuthState](#useauthstate) +- [useRegister](#useregister) +- [useLogin](#uselogin) ### useAuthState @@ -30,6 +32,8 @@ Returns: - `loading`: A `boolean` to indicate whether the the authentication state is still being loaded - `error`: Any `firebase.auth.Error` returned by Firebase when trying to load the user, or `undefined` if there is no error +#### If you are registering or logingIn the user for the first time consider using [useRegister](#useregister), [useLogin](#uselogin) + #### Full Example ```js @@ -70,3 +74,121 @@ const CurrentUser = () => { return ; }; ``` + +### useRegister + +```js +const [registeredUser, error, register, loading] = useRegister( auth, email, password ); +``` + +Import statement : + +```js +import { useRegister } from 'react-firebase-hooks/auth'; +``` + +For full full example [check here](#register-and-login-hook-usage) + +Register a user and receive the user credentials + +The `useRegister` hook takes the following parameters: + +- `auth`: `firebase.auth.Auth` instance for the app you would like to monitor +- `email`: `string` email of the user +- `password`: `string` password of the user + +Returns: + +- `registeredUser`: The `registeredUser` if data is received or `undefined` if not +- `loading`: A `boolean` to indicate whether the the registration is completed or it's yet processing +- `error`: `any` returned by Firebase when trying to register the user, or `undefined` if there is no error +- `register`: `void` a function you can call to start the registration + +### useLogin + +```js +const [loggedInUser, error, login, loading] = useLogin(auth, email, password); +``` + +Import statement : + +```js +import { useLogin } from 'react-firebase-hooks/auth'; +``` + +For full full example [check here](#register-and-login-hook-usage) + +Register a user and receive the user credentials + +The `useLogin` hook takes the following parameters: + +- `auth`: `firebase.auth.Auth` instance for the app you would like to monitor +- `email`: `string` email of the user +- `password`: `string` password of the user + +Returns: + +- `loggedInUser`: The `loggedInUser` if data is received or `undefined` if not +- `loading`: A `boolean` to indicate whether the the login process is completed or it's yet processing +- `error`: `any` returned by Firebase when trying to register the user, or `undefined` if there is no error +- `login`: `void` a function you can call to start the login process + +## Register and Login hook usage + +```jsx +import React, { useState } from 'react'; +import { auth } from './firebase'; +import { useLogin, useRegister } from 'react-firebase-hooks/auth'; + +function App() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [loggedInUser, error, login, loading] = useLogin(auth, email, password); + const [registeredUser, error, register, loading] = useRegister(auth, email, password); + + // Use only one of the above two hooks in one file + + if (error) { + return ( +
+

Error: {error.message}

+
+ ); + } + if (loading) { + return

Loading...

; + } + if (loggedInUser) { + return ( +
+

Currently LoggedIn User: {loggedInUser.email}

+
+ ); + } + if (registeredUser) { + return ( +
+

Currently Registered User: {loggedInUser.email}

+
+ ); + } + return ( +
+ setEmail(e.target.value)} + /> + setPassword(e.target.value)} + /> + + +
+ ); +} + +export default App; +``` diff --git a/auth/index.ts b/auth/index.ts index cfd401d..3164736 100644 --- a/auth/index.ts +++ b/auth/index.ts @@ -1 +1,3 @@ export { default as useAuthState, AuthStateHook } from './useAuthState'; +export { default as useLogin, loginHook } from './useLogin'; +export { default as useRegister, registerHook } from './useRegister'; diff --git a/auth/useAuthState.ts b/auth/useAuthState.ts index fb8b877..ecfb6be 100644 --- a/auth/useAuthState.ts +++ b/auth/useAuthState.ts @@ -18,9 +18,6 @@ export default (auth: firebase.auth.Auth): AuthStateHook => { }; }, [auth]); - const resArray:AuthStateHook = [value, loading, error] - return useMemo( - () => resArray, - resArray, - ); + const resArray: AuthStateHook = [value, loading, error]; + return useMemo(() => resArray, resArray); }; diff --git a/auth/useLogin.ts b/auth/useLogin.ts new file mode 100644 index 0000000..d6c93ee --- /dev/null +++ b/auth/useLogin.ts @@ -0,0 +1,39 @@ +import { useState, useMemo } from 'react'; +import firebase from 'firebase/app'; +import 'firebase/auth'; +import { AuthHookType } from '../util'; + +export type loginHook = AuthHookType< + firebase.auth.UserCredential, + firebase.FirebaseError +>; + +export default ( + auth: firebase.auth.Auth, + email: string, + password: string +): loginHook => { + const [error, setError] = useState(); + const [ + loggedInUser, + setLoggedInUser, + ] = useState(); + const [loading, setLoading] = useState(false); + + const login = () => { + setLoading(true); + auth + .signInWithEmailAndPassword(email, password) + .then((resUser) => { + setLoggedInUser(resUser); + setLoading(false); + }) + .catch((err: firebase.FirebaseError) => { + setError(err); + setLoading(false); + }); + }; + + const resArray: loginHook = [loggedInUser, error, login, loading]; + return useMemo(() => resArray, resArray); +}; diff --git a/auth/useRegister.ts b/auth/useRegister.ts new file mode 100644 index 0000000..f3a4797 --- /dev/null +++ b/auth/useRegister.ts @@ -0,0 +1,38 @@ +import { useState, useMemo } from 'react'; +import firebase from 'firebase/app'; +import { AuthHookType } from '../util'; + +export type registerHook = AuthHookType< + firebase.auth.UserCredential, + firebase.FirebaseError +>; + +export default ( + auth: firebase.auth.Auth, + email: string, + password: string +): registerHook => { + const [error, setError] = useState(); + const [ + registeredUser, + setRegisteredUser, + ] = useState(); + const [loading, setLoading] = useState(false); + + const register = () => { + setLoading(true); + auth + .createUserWithEmailAndPassword(email, password) + .then((resUser) => { + setRegisteredUser(resUser); + setLoading(false); + }) + .catch((err: firebase.FirebaseError) => { + setError(err); + setLoading(false); + }); + }; + + const resArray: registerHook = [registeredUser, error, register, loading]; + return useMemo(() => resArray, resArray); +}; diff --git a/package-lock.json b/package-lock.json index c920b03..46b6ba8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1015,6 +1015,12 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, "pretty-ms": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-3.2.0.tgz", diff --git a/package.json b/package.json index 54cc38a..d3cd23a 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "build": "npm run clean && rollup -c", "clean": "rimraf ./dist ./auth/dist ./auth/*.d.ts ./database/dist ./database/*.d.ts ./firestore/dist ./firestore/*.d.ts ./storage/dist ./storage/*.d.ts ./util/*.d.ts", "dev": "npm run clean && rollup -c -w", - "prepublish": "npm run build" + "prepublish": "npm run build", + "start": "rollup -c -w" }, "main": "dist/index.cjs.js", "module": "dist/index.esm.js", diff --git a/util/index.ts b/util/index.ts index 33edf2e..920a256 100644 --- a/util/index.ts +++ b/util/index.ts @@ -2,3 +2,9 @@ export { default as useLoadingValue } from './useLoadingValue'; export * from './refHooks'; export type LoadingHook = [T | undefined, boolean, E | undefined]; +export type AuthHookType = [ + T | undefined, + E | undefined, + () => void, + boolean +]; diff --git a/util/useLoadingValue.ts b/util/useLoadingValue.ts index f47a958..42f5bd9 100644 --- a/util/useLoadingValue.ts +++ b/util/useLoadingValue.ts @@ -81,13 +81,7 @@ export default (getDefaultValue?: () => T | null): LoadingValue => { setError, setValue, value: state.value, - }), [ - state.error, - state.loading, - reset, - setError, - setValue, - state.value, - ] + }), + [state.error, state.loading, reset, setError, setValue, state.value] ); };