Seems like a trivial issue.
I have an app, where people can subscribe through "stripe". Would like to give access to a few URLs based on subscription, otherwise taking them back to the "profile" page.
A couple of things are not working.
Firebase query to get subscription is not giving results on the subscription. Somehow the onSnapShot does not fetch anything. Probably since UID is null at the start of rendering of page.
Conditional operator on is not working. Not sure what the problem is on this one.
function PaidRoutes(props) {
const [subscription, setSubscription] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const unsub = auth.onAuthStateChanged((authObject) => {
unsub();
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
let docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setLoading(false);
}
});
return () => {
unsub();
};
}, []);
return (
<Route
{...props}
render={(props) =>
subscription ? (
<Component {...props} />
) : (
<Redirect to='/profileScreen' />
)
}
/>
);
Thanks Drew for comment. The installed version of react-router-dom is 5.2.0
Potential issues I see in the PaidRoute code:
loading state is initially false so any check based on it on the initial render won't do what you want. The loading also isn't used to hold off on the conditional rendering.subscription state is initially an empty array which is still truthy, so the conditional logic checking it will likely allow access to the protected route anyway, regardless of any auth status.loading initially true to handle the initial render cycle. Conditionally render null or some loading indicator.subscription state.Code:
function PaidRoutes(props) {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authObject) => {
if (authObject) {
setLoading(true);
const uid = auth.currentUser?.uid;
console.log('UID ==>', uid);
const docRef = query(collection(db, 'customers', uid, 'subscription'));
console.log('DOC REF ==> ', docRef);
onSnapshot(docRef, (snap) => {
snap.forEach((doc) => {
console.log('Role of Subscription', doc.data().role);
setSubscription(doc.data().role);
});
});
} else {
console.log('not logged in');
setSubscription(null); // <-- reset auth state
}
setLoading(false); // <-- clear loading state outside if-else
});
return unsubscribe;
}, []);
if (loading) {
return null; // or loading indicator, spinner, etc...
}
return subscription ? (
<Route {...props} />
) : (
<Redirect to='/profileScreen' />
);
}