Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Created December 18, 2019 16:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanflorence/ae2dd66dffa0fab0f503064d45cc3cc4 to your computer and use it in GitHub Desktop.
Save ryanflorence/ae2dd66dffa0fab0f503064d45cc3cc4 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: "initialCheck",
states: {
initialCheck: {
invoke: {
src: checkAuth,
onDone: [
{
target: "loggedin",
cond: (ctx, event) => event.data,
actions: "setAuth"
},
{
target: "loggedout"
}
],
onError: {
target: "error",
actions: "setError"
}
}
},
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: { target: "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 firebase.auth().signOut()
}
export default Machine(chart, { actions });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment