Hi,
The code below found in App.tsx works fine in the browser but not in the Xcode iOS simulator. In the browser, App.tsx renders twice (loading = true) before the ‘loading’ value changes to false. It renders a total of two times with loading=false thus continuing to the return section of App.tsx. In other words, once the app authenticates the user (previously logged in), then it skips the if condition and continues to the bottom building the menu/routing. This works in both the computer browser and in the browser in the Xcode simulator.
However, in Xcode (app simulator), it only renders once and then nothing happens. Based upon the log (bottom of thread), it goes into the if condition and never produces the 2nd console.log found inside the if condition like it does with the browser. Of course, I get a blank screen on the Xcode similator withe no real errors. Is it a capacitor issue? Any help since I cannot create the iOS app since it won’t work.
App.tsx
import {
IonApp,
IonLoading,
IonRouterOutlet,
IonSplitPane,
setupIonicReact,
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { Redirect, Route, Switch } from "react-router-dom";
// import { AuthContext, useAuthInit } from "./hooks/auth";
import Menu from "./components/Menu";
import Welcome from "./pages/welcome/WelcomePage";
import MainPage from "./pages/main/MainPage";
import VolunteersListPage from "./pages/volunteers/VolunteersListPage";
import VolunteersAddPage from "./pages/volunteers/VolunteersAddPage";
import VolunteersEditPage from "./pages/volunteers/VolunteersEditPage";
import FamiliesListPage from "./pages/families/FamiliesListPage";
// import FamiliesEditPage from "./pages/families/FamiliesEditPage";
import CommunitiesPage from "./pages/communities/CommunitiesPage";
import CampaignsListPage from "./pages/campaigns/CampaignsListPage";
import TurnInTimePage from "./pages/campaigns/TurnInTimePage";
import DonationsPage from "./pages/donations/DonationsPage";
import DeliveriesPage from "./pages/deliveries/DeliveriesPage";
import ReportsPage from "./pages/reports/ReportsPage";
import LogoutPage from "./pages/admin/LogoutPage";
import LoginPage from "./pages/admin/LoginPage";
import RegisterPage from "./pages/admin/RegisterPage";
import SetupPage from "./pages/setup/SetupPage";
import RolesPage from "./pages/setup/RolesPage";
import { useAuthInit, AuthContext } from "./hooks/auth";
setupIonicReact();
const App: React.FC = () => {
const { loading, auth } = useAuthInit();
if (loading) {
console.log("App.tsx - in if loading section: ");
return;
// return <IonLoading isOpen />;
}
console.log(`rendering App with auth:`, auth);
return (
<IonApp>
<AuthContext.Provider value={auth}>
<IonReactRouter>
<IonSplitPane when="lg" contentId="main">
<Menu />
<IonRouterOutlet id="main">
<Switch>
<Route exact path="/login" component={LoginPage} />
<Route exact path="/welcome" component={Welcome} />
<Route exact path="/main" component={MainPage} />
<Route exact path="/register" component={RegisterPage} />
<Route
exact
path="/volunteers/list"
component={VolunteersListPage}
/>
<Route
exact
path="/volunteers/edit/:id"
component={VolunteersEditPage}
/>
<Route
exact
path="/volunteers/add"
component={VolunteersAddPage}
/>
<Route
exact
path="/families/list"
component={FamiliesListPage}
/>
{/* <Route
exact
path="/families/edit/:id"
component={FamiliesEditPage}
/> */}
<Route
exact
path="/campaigns/list"
component={CampaignsListPage}
/>
<Route
exact
path="/campaigns/turnintime"
component={TurnInTimePage}
/>
<Route exact path="/communities" component={CommunitiesPage} />
<Route exact path="/donations" component={DonationsPage} />
<Route exact path="/deliveries" component={DeliveriesPage} />
<Route exact path="/reports" component={ReportsPage} />
<Route exact path="/setup" component={SetupPage} />
<Route exact path="/roles/setup" component={RolesPage} />
<Route exact path="/logout" component={LogoutPage} />
<Route path="/">
<Redirect to="/welcome" />
</Route>
</Switch>
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</AuthContext.Provider>
</IonApp>
);
};
export default App;
auth.ts
import { onAuthStateChanged } from "firebase/auth";
import React, { useContext, useEffect, useState } from "react";
import { auth as firebaseAuth } from "./firebase";
interface Auth {
loggedIn: boolean;
userId?: string;
}
interface AuthInit {
loading: boolean;
auth?: Auth;
}
export const AuthContext = React.createContext<Auth>({ loggedIn: false });
export function useAuth(): Auth {
//custom hook - created instead of using it on everypage
return useContext(AuthContext);
}
export function useAuthInit(): AuthInit {
const [authInit, setAuthInit] = useState<AuthInit>({ loading: true });
useEffect(() => {
return onAuthStateChanged(firebaseAuth, (firebaseUser) => {
const auth = firebaseUser
? { loggedIn: true, userId: firebaseUser.uid }
: { loggedIn: false };
setAuthInit({ loading: false, auth });
});
}, []);
return authInit;
}
Menu.tsx
import {
IonContent,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonMenu,
IonMenuToggle,
IonNote,
} from "@ionic/react";
import "./Menu.css";
import { mainMenuPages, logoutPage } from "../menuData";
import { useAuth } from "../hooks/auth";
import { Redirect } from "react-router-dom";
const Menu: React.FC = () => {
const { loggedIn } = useAuth();
console.log("Menu.tsx - in main function. Value of loggedIn: " + loggedIn);
if (!loggedIn) {
return <Redirect to="/login" />;
}
return (
<IonMenu contentId="main" type="overlay">
<IonContent>
<IonList id="inbox-list">
<IonListHeader>Family to Family</IonListHeader>
<IonNote>St. Louis Catholic Church</IonNote>
{mainMenuPages.map((appPage, index) => {
return (
<IonMenuToggle key={index} autoHide={false}>
<IonItem
className={
location.pathname === appPage.path ? "selected" : ""
}
routerLink={appPage.path}
routerDirection="none"
lines="none"
detail={false}
>
<IonIcon
aria-hiden="true"
slot="start"
ios={appPage.iosIcon}
md={appPage.mdIcon}
/>
<IonLabel>{appPage.title}</IonLabel>
</IonItem>
</IonMenuToggle>
);
})}
</IonList>
<IonList id="labels-list">
{logoutPage.map((appPage, index) => (
<IonItem
lines="none"
key={index}
className={location.pathname === appPage.path ? "selected" : ""}
routerLink={appPage.path}
routerDirection="none"
detail={false}
>
<IonIcon
aria-hiden="true"
slot="start"
ios={appPage.iosIcon}
md={appPage.mdIcon}
/>
<IonLabel>{appPage.title}</IonLabel>
</IonItem>
))}
</IonList>
</IonContent>
</IonMenu>
);
};
export default Menu;
Browser (Chrome) log
App.tsx:60 App.tsx - in if loading section:
App.tsx:60 App.tsx - in if loading section:
App.tsx:65 rendering App with auth: {loggedIn: true, userId: ‘3o9nWIpRBkPTUzRrRyIJ3VAdajz2’}
App.tsx:65 rendering App with auth: {loggedIn: true, userId: ‘3o9nWIpRBkPTUzRrRyIJ3VAdajz2’}
Menu.tsx:20 Menu.tsx - in main function. Value of loggedIn: true
Menu.tsx:20 Menu.tsx - in main function. Value of loggedIn: true
Xcode log
2023-06-27 17:18:04.859797-0400 App[19253:6903201] KeyboardPlugin: resize mode - native
Loading app at capacitor://localhost…
WebView loaded
To Native → SplashScreen hide 121956036
TO JS undefined
[log] - App.tsx - in if loading section: [object Object] true
Main Packages
capacitor/cli 5.0.5
capacitor/core 5.0.5
capacitor/ 5.0.5
ionic/core 7.1.1
ionic/react 7.1.1
ionic/react-router 7.1.1
storage 4.0.0
firebase 9.23.0
firebase-tools 12.4.0