React navigation fail to navigate in APK build. But it works in Development Mode

279 views Asked by At

I have trouble with my app. My app has initial route to Home, then I want to navigate to other screen in HomeStackScreen eg. "Map" screen, then the app restart by itself. The app works fine in development mode, but when it is build in the APK file, the navigation restart the app. What I have tried,

  1. navigation.navigate("Map") // fail in APK, but in development mode it works
  2. navigation.navigate("Home",{screen:"Map"}) // fail in APK, but in development mode it works
  3. navigation.jumpTo("Home",{screen:"Map"}) // fail in APK, but in development mode it works
  4. navigation.push("Map") // fail in APK, but in development mode it works
  5. navigation.replace("Map") // fail in APK, but in development mode it works //
import React, { useState, useEffect, useRef } from "react";
import "react-native-gesture-handler";
import { NavigationContainer, useLinking } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createDrawerNavigator } from "@react-navigation/drawer";
//
import Home from "./Home";
import Map from "./Map";
import Testimoni from "./Testimoni";
import PasienHistory from "./PasienHistory";
import RiwayatPenyakit from "./RiwayatPenyakit";
import RequestTime from "./RequestTime";
import Waiting from "./Waiting";
import DoctorFound from "./DoctorFound";
import Welcome from "./Welcome";
import SignUp from "./SignUp";
import Login from "./Login";
import PasienBaru from "./PasienBaru";
import VerifyCode from "./VerifyCode";
import ListNakes from "./ListNakes";
import RequestStatus from "./RequestStatus";
import CustomRightHeader from "./CustomRightHeader";
import CustomLeftHeader from "./CustomLeftHeader";
import CustomHeaderBackHome from "./CustomHeaderBackHome";
import CustomHeaderBack from "./CustomHeaderBack";
import Loading from "./Loading";
import DrawerContent from "./DrawerContent";
import Profile from "./Profile";
import PatientListHistory from "./PatientListHistory";
import History from "./History";
import HistoryDetail from "./HistoryDetail";
import Transactions from "./Transactions";
import TransactionDetail from "./TransactionDetail";
import Support from "./Support";

//
import * as Permissions from "expo-permissions";
import * as Location from "expo-location";
//
import { Vibration, Platform, View, Text } from "react-native";
import * as Notifications from "expo-notifications";
import Constants from "expo-constants";
import * as Linking from "expo-linking";
//redux
import { useDispatch } from "react-redux";
import firebase from "./config/fbConfig";
//
import { LogBox } from "react-native";

const Drawer = createDrawerNavigator();
const HomeStack = createStackNavigator();
const AuthStack = createStackNavigator();
const ProfileStack = createStackNavigator();
const TransactionStack = createStackNavigator();
const PatientListHistoryStack = createStackNavigator();
const SupportStack = createStackNavigator();

LogBox.ignoreLogs(["Setting a timer"]);

const Index = () => {
  const dispatch = useDispatch();
  const [uid, setUid] = useState(false);

  //expo-linking
  const ref = useRef(null);
  const [isReady, setIsReady] = useState(false);
  const [initialState, setInitialState] = useState();
  const prefix = Linking.makeUrl("/");
  const linkingTo = (path) => {
    const redirectUrl = Linking.makeUrl(path);
    return Linking.openURL(redirectUrl);
  };
  const { getInitialState } = useLinking(ref, {
    prefixes: [prefix],
  });
  //
  const checkLocationPermissionAsync = async () => {
    const { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status === "granted") {
      await Location.hasServicesEnabledAsync().then(async (service) => {
        if (service) {
          return true;
        } else {
          alert("Lokasi tidak aktif");
          return false;
        }
      });
    } else {
      alert("Ijin lokasi tidak aktif");
      return false;
    }
  };
  const checkForPushNotificationsAsync = async () => {
    if (Constants.isDevice) {
      const { status: existingStatus } = await Permissions.getAsync(
        Permissions.NOTIFICATIONS
      );
      let finalStatus = existingStatus;
      if (existingStatus !== "granted") {
        const { status } = await Permissions.askAsync(
          Permissions.NOTIFICATIONS
        );
        finalStatus = status;
      }
      if (finalStatus !== "granted") {
        alert("Ijin notifikasi tidak aktif!");
        return;
      }
    } else {
      alert("Must use physical device for Push Notifications");
    }

    if (Platform.OS === "android") {
      Notifications.setNotificationChannelAsync("default", {
        name: "default",
        importance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: "#FF231F7C",
      });
    }
  };
  const handleNotification = async (notification) => {
    Vibration.vibrate();
    let { identifier } = await notification.request;
    await dispatch({ type: "NOTIFICATION", notification });
    await linkingTo("RequestStatus");
    setTimeout(() => Notifications.dismissNotificationAsync(identifier), 300);
  };
  const handleOnClickNotification = async (response) => {
    let { notification } = response;
    Vibration.vibrate();
    await dispatch({ type: "NOTIFICATION", notification });
    await linkingTo("RequestStatus");
  };
  const onClickNotification = async () => {
    await Notifications.addNotificationResponseReceivedListener(
      handleOnClickNotification
    );
  };
  const listenNotification = async () => {
    await Notifications.addNotificationReceivedListener(handleNotification);
  };

  //
  const onLoad = async () => {
    //expo-linking
    await getInitialState()
      .catch(() => {})
      .then((state) => {
        if (state !== undefined) {
          setInitialState(state);
        }
        setIsReady(true);
      });
    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        user.getIdTokenResult().then((idTokenResult) => {
          if (idTokenResult.claims.patient) {
            setUid(user.uid);
            checkLocationPermissionAsync();
            checkForPushNotificationsAsync();
            listenNotification();
            onClickNotification();
            dispatch({ type: "OFF_LOADING" });
          } else {
            setUid(false);
            dispatch({ type: "OFF_LOADING" });
          }
        });
      } else {
        setUid(false);
        dispatch({ type: "OFF_LOADING" });
      }
    });
  };

  useEffect(() => {
    onLoad();
    // return () => {
    //   setUid(false);
    // };
  }, [getInitialState, uid]);

  const HomeStackScreen = () => (
    <HomeStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <HomeStack.Screen
        name="Home"
        component={Home}
        options={({ navigation }) => ({
          title: "HOMECARE",
          headerLeft: () => <CustomLeftHeader navigation={navigation} />,
          headerRight: () => <CustomRightHeader />,
        })}
      />
      <HomeStack.Screen
        name="Map"
        component={Map}
        options={({ navigation }) => ({
          title: "Tentukan Lokasi Pasien",
        })}
      />
      <HomeStack.Screen
        name="PasienHistory"
        component={PasienHistory}
        options={({ navigation }) => ({
          title: "Pilih Pasien",
        })}
      />
      <HomeStack.Screen
        name="PasienBaru"
        component={PasienBaru}
        options={({ navigation }) => ({
          title: "Pasien Baru",
        })}
      />
      <HomeStack.Screen
        name="RiwayatPenyakit"
        component={RiwayatPenyakit}
        options={({ navigation }) => ({
          title: "Riwayat Penyakit",
        })}
      />
      <HomeStack.Screen
        name="RequestTime"
        component={RequestTime}
        options={({ navigation }) => ({
          title: `Waktu Kunjungan`,
          headerLeft: () => <CustomHeaderBackHome navigation={navigation} />,
        })}
      />
      <HomeStack.Screen
        name="ListNakes"
        component={ListNakes}
        options={({ navigation }) => ({
          title: `Pilih Petugas`,
          headerLeft: () => (
            <CustomHeaderBack navigation={navigation} path={"RequestTime"} />
          ),
        })}
      />

      <HomeStack.Screen
        name="DoctorFound"
        component={DoctorFound}
        options={({ navigation }) => ({
          title: `Petugas Ditemukan`,
          headerLeft: null,
        })}
      />
      <HomeStack.Screen
        name="Waiting"
        component={Waiting}
        options={({ navigation }) => ({
          headerLeft: null,
        })}
      />
      <HomeStack.Screen
        name="RequestStatus"
        component={RequestStatus}
        options={({ navigation }) => ({
          title: `Permintaan Berhasil`,
          headerLeft: () => <CustomHeaderBackHome navigation={navigation} />,
        })}
      />
    </HomeStack.Navigator>
  );

  const AuthStackScreen = () => (
    <AuthStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <AuthStack.Screen name="Welcome" component={Welcome} />
      <AuthStack.Screen
        name="SignUp"
        component={SignUp}
        options={({ navigation }) => ({
          title: `Registrasi`,
        })}
      />
      <AuthStack.Screen name="Login" component={Login} />
      <AuthStack.Screen
        name="VerifyCode"
        component={VerifyCode}
        options={({ navigation }) => ({
          title: `Verifikasi Kode`,
        })}
      />
    </AuthStack.Navigator>
  );
  const TransactionStackScreen = () => (
    <TransactionStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <TransactionStack.Screen
        name="Transactions"
        component={Transactions}
        options={({ navigation }) => ({
          title: `Transaksi`,
          headerLeft: () => <CustomLeftHeader navigation={navigation} />,
        })}
      />
      <TransactionStack.Screen
        name="TransactionDetail"
        component={TransactionDetail}
        options={({ navigation }) => ({
          title: `Detail Transaksi`,
        })}
      />
    </TransactionStack.Navigator>
  );
  const PatientListHistoryStackScreen = () => (
    <PatientListHistoryStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <PatientListHistoryStack.Screen
        name="PatientListHistory"
        component={PatientListHistory}
        options={({ navigation }) => ({
          title: `Pilih Pasien`,
          headerLeft: () => <CustomLeftHeader navigation={navigation} />,
        })}
      />
      <PatientListHistoryStack.Screen name="History" component={History} />
      <PatientListHistoryStack.Screen
        name="HistoryDetail"
        component={HistoryDetail}
        options={({ navigation }) => ({
          title: `Detail History`,
        })}
      />
    </PatientListHistoryStack.Navigator>
  );
  const ProfileStackScreen = () => (
    <ProfileStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <ProfileStack.Screen
        name="Profile"
        component={Profile}
        options={({ navigation }) => ({
          headerLeft: () => <CustomLeftHeader navigation={navigation} />,
        })}
      />
    </ProfileStack.Navigator>
  );
  const SupportStackScreen = () => (
    <SupportStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#29ACE3",
        },
        headerMode: "float",
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#fff",
          fontSize: 14,
        },
        headerTitleAlign: "center",
        headerBackTitleVisible: false,
        headerStatusBarHeight: 20,
      }}
    >
      <SupportStack.Screen
        name="Support"
        component={Support}
        options={({ navigation }) => ({
          headerLeft: () => <CustomLeftHeader navigation={navigation} />,
        })}
      />
    </SupportStack.Navigator>
  );
  if (!isReady) {
    return null;
  }
  return (
    <NavigationContainer
      initialState={initialState}
      ref={ref}
      fallback={<Loading loading={true} />}
    >
      {uid ? (
        <Drawer.Navigator
          initialRouteName="Home"
          drawerContent={(props) => <DrawerContent {...props} />}
        >
          <Drawer.Screen name="Home" component={HomeStackScreen} />
          <Drawer.Screen name="Profile" component={ProfileStackScreen} />
          <Drawer.Screen
            name="Transactions"
            component={TransactionStackScreen}
          />
          <Drawer.Screen
            name="PatientListHistory"
            component={PatientListHistoryStackScreen}
          />
          <Drawer.Screen name="Support" component={SupportStackScreen} />
        </Drawer.Navigator>
      ) : (
        <AuthStackScreen />
      )}
    </NavigationContainer>
  );
};

export default Index;
1

There are 1 answers

1
Moh Jonaidy On

I am sorry, I already has the answer. The problem is not in react navigation but in react-native-maps.