Basic deep linking not working with React Navigation and Redux - react-native

EDIT:
I am wondering if this issue is related to the fact that I have the redux store wrapping the appContainer. Is there another way I am supposed to handle deep linking when using Redux?
I cannot get my deep links to work. They open up the app but do not direct to any page. I have followed directions exactly as is listed here https://reactnavigation.org/docs/en/bottom-tab-navigator.html
I am not sure if it is because of the createSwitchNavigator. I can't figure out how to troubleshoot to figure this out either.
const AppSwitchNavigator = createSwitchNavigator({
Open: { screen: AuthStackNavigator },
Home: {
screen: MainStackNavigator,
path: ''
}
})
const AppContainer = createAppContainer(AppSwitchNavigator)
const PREFIX = 'myApp://';
const App = () => {
return (
<Provider store={store}>
<AppContainer
uriPrefix={PREFIX}
/>
</Provider>
)
}
In MainStackNavigator I have this...
const MainStackNavigator = createStackNavigator(
{
MainTabNavigator: {
screen: MainTabNavigator,
path: ''
},
Contact: {
screen: Contact,
path: 'contact',
},
...
But when i go to myApp://contact - it opens the app but doesn't go the contact screen, and of course, any of the screens in the TabNavigator don't get anywhere either.

Related

Trouble migrating React Navigation v4 Deep Link configuration to React Navigation v5

I'm having some trouble migrating my deep-link from React Navigation v4 to React Navigation v5. 😊
For context, my deep linking has been working perfectly in React Navigation v5 with a tab bar navigator and stack navigators in each tab.
Here's what that looked like:
const MainApp = createBottomTabNavigator(
{
DiscoverTabStack: { screen: DiscoverTabStack, path: "" },
GroupTabStack: { screen: GroupTabStack, path: "" },
ProfileTabStack: { screen: ProfileTabStack, path: "" },
},
);
const DiscoverTabStack = createStackNavigator(
{
Discover: { screen: DiscoverScreen, path: "discover" },
DetailedActivityFromDeepLink: {
screen: DetailedActivityFromDeepLinkScreen,
path: "discover/activites/:id",
},
}
With React Navigation v4, I'm able to successfully deep link into the app to the correct place. However, I'm having some trouble with React Navigation v5. Below is how I'm approaching it with Reach Navigation v5.
const Tab = createBottomTabNavigator();
const DiscoverStack = createStackNavigator();
const prefixes = Linking.makeUrl("myapp://");
const linking = {
prefixes: [prefixes],
config: {
screens: {
DiscoverStack: {
path: "",
screens: {
Discover: {
path: "discover",
},
DetailedActivityFromDeepLink: {
path: "discover/activites/:id",
parse: {
id: (id) => `${id}`,
},
},
},
},
},
},
};
const DiscoverScreens = ({ navigation, route }) => {
return (
<DiscoverStack.Navigator mode="card">
<DiscoverStack.Screen
name="Discover"
component={DiscoverScreen}
/>
<DiscoverStack.Screen
name="DetailedActivityFromDeepLink"
component={DetailedActivityFromDeepLinkScreen}
/>
</DiscoverStack.Navigator>
);
};
render() {
return (
<Container>
<NavigationContainer linking={linking}>
<Tab.Navigator>
<Tab.Screen
name="Discover"
component={DiscoverScreens}
/>
</Tab.Navigator>
</NavigationContainer>
</Container>
);
}
Unfortunately, the above is not working. What may be wrong with my approach? How does one deep-link into an app that has tab bars with stack navigators in each tab?
I'm sure that this is a challenge for the majority of apps out there, so it'll be awesome for some help!! Thanks in advance!
What may be wrong with my approach?
In your root navigator (Tab.Navigator), you call your screen Discover, but in the linking config, you have written DiscoverStack.
The linking config needs to have the same names as you have your screens.

Authentication Flow in React Native

I'm having issue creating the authentication flow of my app. What I actually want is to navigate user conditionally based on their role.
By default, I have created an AuthStack which is basically a stackNavigator and it has a login page. Once user logs in, we receive user's role through a network request. Next I navigate him to a simple home page that returns nothing but switchNavigator based on his role. Here's the code for better clarity.
const AuthStack = createStackNavigator({
Login: {
screen: Login
},
SignUp: {
screen: SignUp
},
Home: {
screen: Home
}
},
{
initialRouteName: 'Login',
headerMode: 'none'
});
const AppContainer = createAppContainer(AuthStack);
const Navigation = () => {
return <AppContainer />
}
When user logs in, I redirect him to Home screen shown in above mentioned stack. Here's the code in Home screen:
const Home = (props) => {
const AppContainer = createAppContainer(RootNavigator(props.user.role))
return <AppContainer />
}
Here I create a new app container (which might be the bad practice, advice please). And RootNavigator is a helper function which returns a switchNavigator:
export const RootNavigator = (user) => {
return createSwitchNavigator({
Admin: {
screen: AdminDrawerNavigator
},
Reporter: {
screen: ReporterDrawerNavigator
}
},
{
initialRouteName: user === 'admin'? 'Admin': 'Reporter'
})
}
This all works fine but it seems switchNavigator doesn't seem to work correctly. If I press back button of hardware, it goes back to login page. Thank you for your time. Please suggest the possible solution.
Try to reset you history navigation :
NavigationActions.reset({
index: 1,
actions: [NavigationActions.navigate({
routeName: 'Admin'
}),
]
});

How to navigate on specific screen from route directory in react native?

I am using react switch navigator from react-navigation library. I create a separate file router.js and call in my App.js. Now i am using react-native-firebase and from the app.js i need to navigate to specific screen. If anyone having an idea then please let me know here is my code:
App.js:
import Router from "./src/Router";
class App extends Component<Props> {
render() {
return (
<Router />
);
}
}
export default App;
Router.js
const AppSwitchNavigator = createSwitchNavigator({
InitialScreen: {
screen: InitialScreen
},
Login: {
screen: Login
},
Forgot: {
screen: Forgot
},
SuccessMessage: {
screen: SuccessMessage
},
App: AppStackDelivery,
AppR: AppStackRecipient,
}, {
initialRouteName: 'InitialScreen'
});
const Router = createAppContainer(AppSwitchNavigator);
export default Router;
From the push notification i am receiving id and i need to navigate to detail screen but i don't get anything to my router or initial screen please anyone having an idea then please share.
You should use the Deep link. And go to the path you want in onNotification.
Example
handleNotification () {
const path = "chat/Eric";
const prefix = Platform.OS === 'android'
? 'myapp://myapp/'
: 'myapp://'
const url = `${prefix}${path}`;
Linking.openURL(url).catch(err => console.error(err));
firebase.messaging().setBadgeNumber(0);
}

How to organize navigation structure in React Native?

I'm using react-navigation library. Currently the navigation is organized in this way:
App.js:
const Layout = createRootNavigator(signedIn);
return (
<AppFontLoader>
<Layout />
</AppFontLoader>
);
AppNavigator:
export const createRootNavigator = (signedIn = false) => {
return createSwitchNavigator(
{
SignedIn: {
screen: SignedIn
},
SignedOut: {
screen: SignedOut
}
},
{
initialRouteName: signedIn ? "SignedIn" : "SignedOut"
}
);
};
AppNavigator:
export const SignedIn = createMaterialBottomTabNavigator(
{
MeetingsScreen: {
...
}
MeetingsScreen:
const MeetingNavigator = createStackNavigator({
MeetingsListScreen: {
screen: MeetingsListScreen,
navigationOptions: {
}
},
AddMeetingForm: {
screen: AddMeetingFormScreen
},
MeetingScreen: {
screen: MeetingScreen
}
}, {initialRouteName: "MeetingsListScreen"});
The error is shown with the current structure:
You should only render one navigator explicitly in your app, and other navigators should by rendered by including them in that navigator.
Apparently, I shouldn't nest one navigator into another, but I'm struggling to come up with the right navigation structure.
How to organize the navigation so that I can have more layers of navigation to move between screens?
I've encountered the same issue, so what I ended up doing was just making one navigation. Rootstack. All routes are there. My app.js has only root stack and navigations.

React native login state across entire app

My home screen exists of a StackNavigator which is inside a DrawerNavigator. Code:
const HomeNavigator = StackNavigator({
Index: { screen: ScreenHome },
Register: { screen: ScreenRegister },
});
const App = DrawerNavigator({
Home: { screen: HomeNavigator }
},{
contentComponent: (navigation) => <ScreenMenu navigation={navigation}/>
});
AppRegistry.registerComponent('ReactApp', () => App);
After logging in through a REST Service i want to pass the loggedIn state to all my other screens. But how should i do this? Should i declare a Authentication Component which will be passed to all the screens? Or is there another best practice for a global login state?
You could use redux for setting up a global state for the app.