@fluido/react-profile-manager
Version:
Fluido profile manager
138 lines (137 loc) • 5.88 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useProfile = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const auth_1 = require("firebase/auth");
const firestore_1 = require("firebase/firestore");
const messaging_1 = require("firebase/messaging");
const react_1 = require("react");
const ProfileContext = (0, react_1.createContext)({
ready: false,
logged: false,
user: null,
token: null,
FCMToken: null,
FCMState: null,
claims: {},
});
const useProfile = () => (0, react_1.useContext)(ProfileContext);
exports.useProfile = useProfile;
function ProfileProvider({ children, firebaseApp, refreshTokenTime = 20, pathname, FCMKey, onCallRedirectToPublic, onCallRedirectToAuthenticated, unauthenticatedRoutes = ['/login'], authenticatedRoutes = [], }) {
// Profile Provider
const [ready, setReady] = (0, react_1.useState)(false);
const [user, setUser] = (0, react_1.useState)(null);
const [token, setToken] = (0, react_1.useState)(null);
const [FCMToken, setFCMToken] = (0, react_1.useState)(null);
const [FCMState, setFCMState] = (0, react_1.useState)();
const [claims, setClaims] = (0, react_1.useState)();
(0, react_1.useLayoutEffect)(() => {
let unregisterSnaps = [];
const auth = (0, auth_1.getAuth)(firebaseApp);
const unregister = (0, auth_1.onAuthStateChanged)(auth, (user) => {
unregisterSnaps.forEach((e) => e());
unregisterSnaps = [];
setUser(user);
if (user) {
const db = (0, firestore_1.getFirestore)(firebaseApp);
const userRef = (0, firestore_1.doc)(db, `users/${user.uid}`);
const claimsRef = (0, firestore_1.collection)(userRef, `claims`);
unregisterSnaps.push((0, firestore_1.onSnapshot)(claimsRef, (snapshot) => {
setReady(true);
user.getIdToken(true).then((token) => {
setToken(token);
});
if (!snapshot.empty) {
setClaims(snapshot.docs.reduce((prev, doc) => {
return Object.assign(Object.assign({}, prev), { [doc.id]: Object.values(doc.data()) });
}, {}));
}
else {
setClaims({});
}
}));
const timerId = setInterval(() => user.getIdToken(true).then((token) => {
setToken(token);
}), 1000 * refreshTokenTime);
unregisterSnaps.push(() => clearInterval(timerId));
}
else {
setReady(true);
setToken(null);
}
});
return () => {
unregister();
unregisterSnaps.forEach((e) => e());
};
}, []);
// Page blocker
(0, react_1.useLayoutEffect)(() => {
if (!ready)
return;
if (!user && authenticatedRoutes.includes(pathname)) {
onCallRedirectToPublic && onCallRedirectToPublic();
}
else if (!!user && unauthenticatedRoutes.includes(pathname)) {
onCallRedirectToAuthenticated && onCallRedirectToAuthenticated();
}
}, [ready, !!user, pathname]);
// FCM Loader
(0, react_1.useLayoutEffect)(() => {
if (!FCMKey)
return;
setFCMState('loading');
setFCMToken(null);
try {
const messaging = (0, messaging_1.getMessaging)(firebaseApp);
(0, messaging_1.getToken)(messaging, { vapidKey: FCMKey })
.then((token) => __awaiter(this, void 0, void 0, function* () {
if (token) {
setFCMToken(token);
setFCMState('ready');
}
else {
setFCMState('required');
}
}))
.catch((err) => {
if (err.message.includes('permission-blocked')) {
setFCMState('required');
}
else {
console.log(err);
}
setFCMState('error');
});
}
catch (err) {
setFCMState('error');
}
}, [FCMKey]);
(0, react_1.useLayoutEffect)(() => {
if (ready && !!user && FCMToken && FCMState === 'ready') {
const db = (0, firestore_1.getFirestore)();
const userDoc = (0, firestore_1.doc)(db, `users/${user.uid}`);
(0, firestore_1.setDoc)(userDoc, { fcm: FCMToken }, { merge: true });
}
}, [ready, !!user, FCMToken, FCMState]);
return ((0, jsx_runtime_1.jsx)(ProfileContext.Provider, Object.assign({ value: {
user,
logged: !!user,
claims,
ready,
token,
FCMToken,
FCMState,
} }, { children: children }), void 0));
}
exports.default = ProfileProvider;