I've built a simple application that loads a page using Webview and, even though I've allowed cookies and cache, once the app is closed, the user is logged out from the website. PS.: This only happens in iOS devices, not in Android.
import React from 'react';
import WebView from 'react-native-webview';
import { useNavigation } from '#react-navigation/native';
const WebViewPage = () => {
const { navigate } = useNavigation();
return (
<WebView
source={{ uri: 'my-url' }}
onError={() => navigate('Error')}
thirdPartyCookiesEnabled
allowFileAccess
cacheEnabled
sharedCookiesEnabled
/>
);
};
export default WebViewPage;
I've found solutions for Flutter applications, but not for React-native.
Related
I have a react-native app (expo managed) and in this app I need to open a couple of webviews ( that are hosted on my website url). The issue is that when I update the content on the website, react-native webview still has the old website's content.
For example, react-native opens a webview page with a title Library, I've updated the title to Libraries and deployed the changes to my website, when I open the website (though phone/desktop) I see the title Libraries, but when I open the same page as the webview from the react-native app the title is still Library. If I delete and reinstall the react-native app then I see Libraries, I can't seem to figure out what may cause this issue.
This is my code:
import React, {useRef, useEffect} from 'react';
import { WebView } from 'react-native-webview';
const webViewRef = useRef();
useEffect(() => {
webViewRef.current.reload();
}, []);
WebView
bounces={false}
ref={(ref) => (webViewRef.current = ref)}
source={{uri: "mywebsite"}}
/>
Any advise or help is greatly appreciated
I was able to fix this issue by passing a vavlue to the url,
import React, {useRef, useEffect, **useState**} from 'react';
import { WebView } from 'react-native-webview';
const webViewRef = useRef();
**const [value, setValue] = useState()**
useEffect(() => {
webViewRef.current.reload();
*setValue(Math.random)*
}, []);
WebView
bounces={false}
ref={(ref) => (webViewRef.current = ref)}
source={{uri: **`mywebsite?var=${value}`**}}
This allows webview url to refresh on page load
Some background for context...I'm creating a react-native app that will live in it's own repository. This app will be integrated into other web, iOS, and Android apps. I'm currently working with the Android app. This is an existing native app written in Java.
I've "wrapped" it with a super basic React Native app, following the React Native Docs. For testing purposes, to mimic what will end up being the production app, I have a native activity, MainActivity in the Android app, with a button that opens the second activity, ReactNativeActivity which is loads my React Native app. This is working - the React Native app loads. The React Native App has a button that should navigate to a second screen within the React Native app (using react-navigation). When I press that button, instead of navigating to the next screen in my stack, it instead reloads MainActivity from the native Android app. Running the same thing on web there is no issue with navigation, so I know the screens are hooked up right. I'm not new to React Native, but I am new to integrating with existing Native applications.
Edited to add some code as requested
The Navigator and the button are as follows:
// navigator.tsx
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { HomeScreen } from "../screens/Home";
import Demo from "../screens/Demo";
export type NavigationStackParamList = {
HomeScreen: undefined;
Demo: undefined;
};
const Stack = createNativeStackNavigator<NavigationStackParamList>();
export const Navigation = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen component={Demo} name="Demo" />
<Stack.Screen
component={HomeScreen}
name="HomeScreen"
options={{ title: "Home" }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
// Demo Screen
const Demo: React.FC<DemoScreenProps> = ({ navigation }) => {
return (
<View style={styles.app}>
<View style={styles.info}>
<Text style={styles.title}>Demo</Text>
<Text>Running on: </Text>
<Text style={styles.platform}>{Platform.OS}</Text>
</View>
<Map />
<Button
onPress={() => navigation.navigate("HomeScreen")}
title="Go to Test Screen"
/>
</View>
);
};
Pressing "Go to Test Screen" above, is what is causing the MainActivity to reload, rather than the correct screen.
I am building an app to show information of how covid is affected by different factors, like climate, and co2 level. So I used a webview to bring in a map from NASA. But when I navigate to that specific screen. The app crashes. It works fine sometimes, and crash mostly. My code is
import { StyleSheet, Text, View } from 'react-native'
import { WebView } from 'react-native-webview';
const GreenHouseScreen = () => {
return (
<View>
<WebView
style={{width: 600, height: 500}}
source={{uri: 'https://eodashboard.org/iframe?poi=W4-N2'}}
/>
</View>
)
}
export default GreenHouseScreen```
I'm using loadAsync to load some fonts. It worked fine while testing the app on my device, but when I tried on another device (Galaxy s10e), the fonts seem to be loaded (checking with Font.isLoaded) but not displaying when using fontFamily.
This is my App.js
import * as Font from 'expo-font';
import {AppLoading} from 'expo';
import React, {useState} from 'react';
const fetchFonts = async() => {
return await Font.loadAsync ({
secular: require ('./assets/fonts/SecularOne-Regular.ttf'),
varela: require ('./assets/fonts/VarelaRound-Regular.ttf'),
lemon: require ('./assets/fonts/LemonMilk.otf'),
collegiate: require ('./assets/fonts/CollegiateBlackFLF.ttf'),
assistant: require ('./assets/fonts/Assistant-ExtraBold.ttf'),
zvulun: require ('./assets/fonts/zvulun-black-fm.otf'),
roboto: require ('./assets/fonts/Roboto-Medium.ttf'),
osh: require ('./assets/fonts/OpenSansHebrew-ExtraBold.ttf'),
oshregular: require ('./assets/fonts/OpenSansHebrew-Regular.ttf'),
oshlight: require('./assets/fonts/OpenSansHebrew-Light.ttf'),
myriad: require('./assets/fonts/myriad-hebrew.ttf')
});
};
export default function App () {
const [dataLoaded, setDataLoaded] = useState (false);
if (!dataLoaded) {
return (
<AppLoading
startAsync={() => fetchFonts().then(() => console.log('done')).catch((err) => console.log(err))}
onFinish={() => setDataLoaded (true)}
onError={err => console.log (err)}
/>
);
}
return *the actual app*;
}
To be clear, the fonts do load and show correctly on another device (Galaxy s10+).
Expo SDK 37
Android 11
expo-font 8.1.0
i am creating a very simple app for android and iphone/ipad that uses only webview.
How can i store username and password so the user would not have to type them in every single time. Thanks in advance.
import React, { Component } from 'react';
import {
AppRegistry,
WebView
} from 'react-native';
export default class myapp extends Component {
render() {
return (
<WebView
source={{uri: 'https://mysecretappurl.com'}}
/>
);
}
}
AppRegistry.registerComponent('myapp', () => myapp);
Thank you Fabian for a quick response.
I got it solved with injectedJavascript and the data persist even if i close and relaunch the app both on android and ios. I got stuck as at first as tried to go with asyncstorage and reactnativ-webview-bridge but i failed to implement them due to my lack of knowledge.
import React, { Component } from 'react';
import {
AppRegistry,
WebView
} from 'react-native';
export default class myapp extends Component {
render() {
let jsCode = `
var cookie={};
document.cookie.split('; ').forEach(function(i){cookie[i.split('=')[0]]=i.split('=')[1]});
document.querySelector('#email').value=cookie['email'] || '';
document.querySelector('#password').value=cookie['password'] || '';
document.querySelector('#login button').onclick = function(){
document.cookie = 'email='+document.querySelector('#email').value;
document.cookie = 'password='+document.querySelector('#password').value;
};
`;
return (
<WebView
source={{uri: 'https://mysecretappurl.com'}}
injectedJavaScript={jsCode}
/>
);
}
}
AppRegistry.registerComponent('myapp', () => myapp);
I don't know if I understand you correctly:
You are writing a "minified browser" with react native only to show your webpage and you want to prefill the login form on that page?
If it's true you are searching for a possibility to exchange data from your React Native app with your page in the WebView component. Take a look at this tutorial of react-native-webview-bridge .
I would try the following:
Communicate with your Webpage and establish a listener for your login form to pass the credentials to your RN app
Use a module like react-native-simple-store to store the credentials in your RN app
If you start the app the next time check your storage and if the credentials are not empty send them to your webpage via bridge/injected javascript