-
Notifications
You must be signed in to change notification settings - Fork 27.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Examples] remove getInitialProps from with-firebase-authentication (#…
- Loading branch information
1 parent
1c057e7
commit 6c8b7cd
Showing
21 changed files
with
122 additions
and
580 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
examples/with-firebase-authentication/pages/api/getFood.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { verifyIdToken } from '../../utils/auth/firebaseAdmin' | ||
const favoriteFoods = ['pizza', 'burger', 'chips', 'tortilla'] | ||
|
||
const getFood = async (req, res) => { | ||
const token = req.headers.token | ||
|
||
try { | ||
await verifyIdToken(token) | ||
return res.status(200).json({ | ||
food: favoriteFoods[Math.floor(Math.random() * favoriteFoods.length)], | ||
}) | ||
} catch (error) { | ||
return res.status(401).send('You are unauthorised') | ||
} | ||
} | ||
|
||
export default getFood |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,4 @@ const Auth = () => { | |
) | ||
} | ||
|
||
Auth.propTypes = {} | ||
|
||
export default Auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,60 @@ | ||
import PropTypes from 'prop-types' | ||
import { get } from 'lodash/object' | ||
import useSWR from 'swr' | ||
import Link from 'next/link' | ||
import Router from 'next/router' | ||
import withAuthUser from '../utils/pageWrappers/withAuthUser' | ||
import withAuthUserInfo from '../utils/pageWrappers/withAuthUserInfo' | ||
import logout from '../utils/auth/logout' | ||
|
||
const Index = (props) => { | ||
const { AuthUserInfo, data } = props | ||
const AuthUser = get(AuthUserInfo, 'AuthUser', null) | ||
const { favoriteFood } = data | ||
import { useUser } from '../utils/auth/useUser' | ||
|
||
const fetcher = (url, token) => | ||
fetch(url, { | ||
method: 'GET', | ||
headers: new Headers({ 'Content-Type': 'application/json', token }), | ||
credentials: 'same-origin', | ||
}).then((res) => res.json()) | ||
|
||
const Index = () => { | ||
const { user, logout } = useUser() | ||
const { data, error } = useSWR( | ||
user ? ['/api/getFood', user.token] : null, | ||
fetcher | ||
) | ||
|
||
return ( | ||
<div> | ||
<p>Hi there!</p> | ||
{!AuthUser ? ( | ||
if (!user) { | ||
return ( | ||
<> | ||
<p>Hi there!</p> | ||
<p> | ||
You are not signed in.{' '} | ||
<Link href={'/auth'}> | ||
<a>Sign in</a> | ||
</Link> | ||
</p> | ||
) : ( | ||
<div> | ||
<p>You're signed in. Email: {AuthUser.email}</p> | ||
<p | ||
style={{ | ||
display: 'inlinelock', | ||
color: 'blue', | ||
textDecoration: 'underline', | ||
cursor: 'pointer', | ||
}} | ||
onClick={async () => { | ||
try { | ||
await logout() | ||
Router.push('/auth') | ||
} catch (e) { | ||
console.error(e) | ||
} | ||
}} | ||
> | ||
Log out | ||
</p> | ||
</div> | ||
)} | ||
</> | ||
) | ||
} | ||
|
||
return ( | ||
<div> | ||
<div> | ||
<p>You're signed in. Email: {user.email}</p> | ||
<p | ||
style={{ | ||
display: 'inlinelock', | ||
color: 'blue', | ||
textDecoration: 'underline', | ||
cursor: 'pointer', | ||
}} | ||
onClick={() => logout()} | ||
> | ||
Log out | ||
</p> | ||
</div> | ||
<div> | ||
<Link href={'/example'}> | ||
<a>Another example page</a> | ||
</Link> | ||
</div> | ||
<div> | ||
<div>Your favorite food is {favoriteFood}.</div> | ||
</div> | ||
{error && <div>Failed to fetch food!</div>} | ||
{data && <div>Your favorite food is {data.food}.</div>} | ||
</div> | ||
) | ||
} | ||
|
||
// Just an example. | ||
const mockFetchData = async (userId) => ({ | ||
user: { | ||
...(userId && { | ||
id: userId, | ||
}), | ||
}, | ||
favoriteFood: 'pizza', | ||
}) | ||
|
||
Index.getInitialProps = async (ctx) => { | ||
// Get the AuthUserInfo object. This is set in `withAuthUser.js`. | ||
// The AuthUserInfo object is available on both the server and client. | ||
const AuthUserInfo = get(ctx, 'myCustomData.AuthUserInfo', null) | ||
const AuthUser = get(AuthUserInfo, 'AuthUser', null) | ||
|
||
// You can also get the token (e.g., to authorize a request when fetching data) | ||
// const AuthUserToken = get(AuthUserInfo, 'token', null) | ||
|
||
// You can fetch data here. | ||
const data = await mockFetchData(get(AuthUser, 'id')) | ||
|
||
return { | ||
data, | ||
} | ||
} | ||
|
||
Index.displayName = 'Index' | ||
|
||
Index.propTypes = { | ||
AuthUserInfo: PropTypes.shape({ | ||
AuthUser: PropTypes.shape({ | ||
id: PropTypes.string.isRequired, | ||
email: PropTypes.string.isRequired, | ||
emailVerified: PropTypes.bool.isRequired, | ||
}), | ||
token: PropTypes.string, | ||
}), | ||
data: PropTypes.shape({ | ||
user: PropTypes.shape({ | ||
id: PropTypes.string, | ||
}).isRequired, | ||
favoriteFood: PropTypes.string.isRequired, | ||
}).isRequired, | ||
} | ||
|
||
Index.defaultProps = { | ||
AuthUserInfo: null, | ||
} | ||
|
||
// Use `withAuthUser` to get the authed user server-side, which | ||
// disables static rendering. | ||
// Use `withAuthUserInfo` to include the authed user as a prop | ||
// to your component. | ||
export default withAuthUser(withAuthUserInfo(Index)) | ||
export default Index |
Oops, something went wrong.
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was great, but I'm sure you meant to remove
.env.local.example
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason why .env.local.example is removed?
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great! I wish I would have waited until today to start my latest project :P
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will there be another place where the old version of this will be stored? Some sites just really need SSR -- and not having a resource to configure Firebase with it is going to be awful.
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to set a cookie in this example, given that the Firebase user is only loaded client-side. Instead, it should just use the Firebase SDK. In fact, this example might be providing an expired Firebase ID token to the app if the token's stored in the cookie longer than an hour and isn't refreshed.
6c8b7cd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matteing I agree. Opened an issue here: #14783
Note that the previous Firebase SSR auth example (which this commit replaced) was flawed if you needed to use the Firebase ID token on the server side. The Firebase ID token was stored in a cookie and would expire after 1 hour, so often the server side wouldn't have a usable token. It worked fine if you only needed the Firebase user's ID or email, though.