Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ npm-debug.log
# Testing output
.nyc_output
coverage

#test files
/example
122 changes: 122 additions & 0 deletions auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { useAuthState } from 'react-firebase-hooks/auth';
List of Auth hooks:

- [useAuthState](#useauthstate)
- [useRegister](#useregister)
- [useLogin](#uselogin)

### useAuthState

Expand All @@ -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
Expand Down Expand Up @@ -70,3 +74,121 @@ const CurrentUser = () => {
return <button onClick={login}>Log in</button>;
};
```

### 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 (
<div>
<p>Error: {error.message}</p>
</div>
);
}
if (loading) {
return <p>Loading...</p>;
}
if (loggedInUser) {
return (
<div>
<p>Currently LoggedIn User: {loggedInUser.email}</p>
</div>
);
}
if (registeredUser) {
return (
<div>
<p>Currently Registered User: {loggedInUser.email}</p>
</div>
);
}
return (
<div className="App">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={login}>SIGN IN</button>
<button onClick={register}>SIGN UP</button>
</div>
);
}

export default App;
```
2 changes: 2 additions & 0 deletions auth/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { default as useAuthState, AuthStateHook } from './useAuthState';
export { default as useLogin, loginHook } from './useLogin';
export { default as useRegister, registerHook } from './useRegister';
7 changes: 2 additions & 5 deletions auth/useAuthState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ export default (auth: firebase.auth.Auth): AuthStateHook => {
};
}, [auth]);

const resArray:AuthStateHook = [value, loading, error]
return useMemo<AuthStateHook>(
() => resArray,
resArray,
);
const resArray: AuthStateHook = [value, loading, error];
return useMemo<AuthStateHook>(() => resArray, resArray);
};
39 changes: 39 additions & 0 deletions auth/useLogin.ts
Original file line number Diff line number Diff line change
@@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to make email and password variables that are passed into the returned login function. This is more in keeping with what some of the other libraries that allow mutation of data, e.g. apollo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I was thinking about the exact same thing

password: string
): loginHook => {
const [error, setError] = useState<firebase.FirebaseError>();
const [
loggedInUser,
setLoggedInUser,
] = useState<firebase.auth.UserCredential>();
const [loading, setLoading] = useState<boolean>(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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a return perspective, I think that the function should be returned as the first item in the array and the order of the other elements should match the order of useAuthState.

So it should be: [login, loggedInUser, loading, error]

return useMemo<loginHook>(() => resArray, resArray);
};
38 changes: 38 additions & 0 deletions auth/useRegister.ts
Original file line number Diff line number Diff line change
@@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, I think it would be better to make email and password variables that are passed into the returned register function

password: string
): registerHook => {
const [error, setError] = useState<firebase.FirebaseError>();
const [
registeredUser,
setRegisteredUser,
] = useState<firebase.auth.UserCredential>();
const [loading, setLoading] = useState<boolean>(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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, the ordering should match what's proposed for login

return useMemo<registerHook>(() => resArray, resArray);
};
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ export { default as useLoadingValue } from './useLoadingValue';
export * from './refHooks';

export type LoadingHook<T, E> = [T | undefined, boolean, E | undefined];
export type AuthHookType<T, E> = [
T | undefined,
E | undefined,
() => void,
boolean
];
10 changes: 2 additions & 8 deletions util/useLoadingValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,7 @@ export default <T, E>(getDefaultValue?: () => T | null): LoadingValue<T, E> => {
setError,
setValue,
value: state.value,
}), [
state.error,
state.loading,
reset,
setError,
setValue,
state.value,
]
}),
[state.error, state.loading, reset, setError, setValue, state.value]
);
};