Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active July 20, 2022 19:03
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ryanflorence/4f7e8759d980489f309a4ae2ebd31904 to your computer and use it in GitHub Desktop.
Save ryanflorence/4f7e8759d980489f309a4ae2ebd31904 to your computer and use it in GitHub Desktop.
import { Machine, assign } from 'xstate';
import firebase from './firebase';
const chart = {
id: 'auth',
context: {
auth: null,
error: null,
loggedoutTime: null
},
initial: 'checking',
states: {
checking: {
invoke: {
src: checkAuth,
onDone: [
{
target: 'loggedin',
cond: (ctx, event) => event.data,
actions: 'setAuth'
},
{
target: 'loggedout'
}
],
onError: {
target: 'error',
actions: 'setError'
}
}
},
loggedin: {
on: {
LOG_OUT: 'signingOut'
}
},
signingOut: {
invoke: {
src: logout,
onDone: {
target: 'loggedout',
actions: ['clearAuth', 'setLoggedoutTime']
},
onError: {
target: 'error',
actions: 'setError'
}
}
},
loggedout: {
on: {
LOG_IN: 'signingIn'
}
},
signingIn: {
invoke: {
src: login,
onDone: {
target: 'loggedin',
cond: (ctx, event) => event.data,
actions: 'setAuth'
},
onError: {
target: 'error',
actions: 'setError'
}
}
},
error: {
on: {
RETRY: 'checking',
actions: 'resetContext'
}
}
}
};
const actions = {
resetContext: assign({
auth: null,
error: null,
loggedoutTime: null
}),
clearAuth: assign({
auth: null
}),
setLoggedoutTime: assign({
loggedoutTime: () => new Date()
}),
setAuth: assign({
loggedoutTime: null,
auth: (
ctx,
{
data: {
displayName,
email,
emailVerified,
photoURL,
uid
}
}
) => ({
displayName,
email,
emailVerified,
photoURL,
uid
})
}),
setError: assign({
error: (ctx, event) => event.data
})
};
function checkAuth() {
return new Promise((resolve, reject) => {
const unsubscribe = firebase.auth().onAuthStateChanged(auth => {
unsubscribe();
resolve(auth);
});
});
}
async function login() {
let provider = new firebase.auth.GoogleAuthProvider();
let result = await firebase.auth().signInWithPopup(provider);
return result.user
}
function logout() {
return Promise.all([
firebase.auth().signOut(),
// when it's too fast it doesn't feel like it worked 😂
new Promise(resolve => setTimeout(resolve, 1000))
])
}
export default Machine(chart, { actions });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment