How can I access login action response in webview in react native? - react-native

I want to reach the response returned after login in webview. But after a lot of research, I couldn't come to a conclusion.
Welcome screen. Here I am redirecting to the webview by clicking the button.
Login screen(Webview). I need to reach the response returned after logging in here.
How can I access requests and responses in webview? Or what is the correct way?

you can use injected script to send data to webview ,and postMessage to send data back to react native app
//This sends data from WebView to React Native
...
<script>
window.postMessage("Sending data from WebView");
</script>
...
//In order to get data the was sent from WebView use onMessage prop on <WebView>
...
<WebView
ref="webview"
injectedJavaScript={`
document.body.style.backgroundColor = '#f4f4f4';
true; `}
onMessage={this.onMessage}
/>
onMessage(data) {
//Prints out data that was passed.
console.log(data);
}

Related

Passing Login Details to React Native WebView

I'm trying to pass login details to a WebView, basically, my use case is, I have a login page built with React Native, after a successful login I wanted to redirect the user to a WebView login with the login details so the WebView doesn't render the login page in itself. So, to achieve this I attach the ref to webView like so
<WebView ref={webViewRef} ... />
With the login page built with ReactNative, the user will enter their credentials, once the login is successful I'll get the user details from the backend as a response to the LOGIN Post API Call, so I passed the response to the postMessage function
const response = await LOGIN({...credentials});
webviewRef.current.postMessage(response.data);
And to the React Web app, I used the below code to add the listener
window.addEventListener("message", (message) => {
alert(JSON.stringify(message.data));
});
But, I'm not getting the data with message.data.
Any workaround would highly be appreciated
You have to use injectJavaScript method on the webviewRef to send data from the app to the web(i.e., to react side). The post message will be used vice-versa i.e., to send data from react side to the app side. The solution below would solve your issue.
First on react side, set the custom function on the window object.
window.onUserLogin = function(userDetails) {
alert(`userDetails are ${JSON.stringify(userDetails)}`)
}
Now on the react-native side, you have the webViewRef. Using that please make the below call.
const USER_DETAILS = {
userName: "Haider"
};
webViewRef.current.injectJavaScript(`window.onUserLogin(${JSON.stringfy(USER_DETAILS)});true;`)

how to exit webview after submit in react native

If using webview for user login, we want to close the webview automatically after user submit their info. How to achieve that?
I have seen this being done when using Facebook sign in library, when user login with Facebook, it closes the website and calls the callback.
I am using 'react-native-inappbrowser-reborn'
you can do it use webView interact with js. firstly, when the user clicks the login button to submit their info, the html can post a message use window.postMessage("content") ., then in the react-native webview add onMessage handle.
<WebView
onMessage={this.onMessage}
...
/>
onMessage = (message) => {
// the message is you posted by window.postMessage
}
for react-native > 0.6; you should change to use window.ReactNativeWebView.postMessage.
Besides that, you can also use the injectJavaScripts. for more details about webview interact with js, you can read this artticle

How to redirect to notification page when app is opened after clicking FCM notification?

I have implemented firebase cloud messaging in my app successfully. But when a new notification appears, my app should open and then redirect to the notifications page from app.js.
The app is showing log info when the notification is clicked but when I try this.props.navigator.push("Notification"); in that function, it shows an error undefined is not an object(evaluating this.props.navigation.push)
I am guessing this is because I haven't yet initialised my stacknavigator but I don't know this for sure. I am using react-navigation in my app.
Here is the function in my app.js that gets called when the notification is clicked.
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
console.log('getInitialNotification:');
this.props.navigator.push("Notification");
}
Also, the navigation code is not working even in my render function in app.js so I think props is not initialised in app.js.
Can anyone help me fix this and land me to the notification page?
Considering you have a route called Notification in your stack navigator and also your app.js has access to the navigator's navigation prop, then you might want to use this.props.navigation.navigate('Notification') in case you are using react-navigation.
The problem with your code is this.props.navigation doesn't have any method called push so it will surely give an undefined error. To know more about navigation prop consider going through this doc.

React Native preload local images

How do I load images before Rendering in React Native
I use the map.
And i use custom image for markers.
I want to load the marker images before loading maps (or before rendering)
RN Image component a specific static method to handle this case: https://facebook.github.io/react-native/docs/image.html#prefetch
Note: Image.prefetch returns a Promise
Below is an example of how to implement this using React Native Router Flux (RNRF), without using Redux:
let urlOfImages = [https://...]
let preFetchTasks = [];
urlOfImages.forEach((p)=>{
preFetchTasks.push(Image.prefetch(p));
});
Promise.all(preFetchTasks).then((results)=>{
let downloadedAll = true;
results.forEach((result)=>{
if(!result){
//error occurred downloading a pic
downloadedAll = false;
}
})
if(downloadedAll){
Actions.someScene({ downloadedPics: urlOfImages})
}
})
Then in your someScene component use the image component like you normally do and the image will be fetched from your local disk cache rather then remotely :
<Image style={...} source={{uri: this.props.urlOfImages[0]}} />
Also just be aware you'll have issues if you attempt to load images from http rather than secured https endpoints: https://github.com/facebook/react-native/issues/8520
If you wanted to use it with Redux put the above code in an Action and make sure your reducers respond to the action and set the new state as per your application requirements.
Resource: https://stackoverflow.com/a/42710306/6569224

Preload images before navigating to component

This is more of a conceptional question, but I am not sure the exact way to solve it.
I have a component I want to download images from, but I want to be able to indicate that the component is loaded before the user can then use router flux to switch to it.
I am guessing that is something I would have to accomplish in redux, is that the right idea? I've been trying to find an example of a react native app that does this.
Thanks so much!
RN Image component a specific static method to handle this case: https://facebook.github.io/react-native/docs/image.html#prefetch
Note: Image.prefetch returns a Promise
Below is an example of how to implement this using React Native Router Flux (RNRF), without using Redux:
let urlOfImages = [https://...]
let preFetchTasks = [];
urlOfImages.forEach((p)=>{
preFetchTasks.push(Image.prefetch(p));
});
Promise.all(preFetchTasks).then((results)=>{
let downloadedAll = true;
results.forEach((result)=>{
if(!result){
//error occurred downloading a pic
downloadedAll = false;
}
})
if(downloadedAll){
Actions.someScene({ downloadedPics: urlOfImages})
}
})
Then in your someScene component use the image component like you normally do and the image will be fetched from your local disk cache rather then remotely :
<Image style={...} source={{uri: this.props.urlOfImages[0]}} />
Also just be aware you'll have issues if you attempt to load images from http rather than secured https endpoints: https://github.com/facebook/react-native/issues/8520
If you wanted to use it with Redux put the above code in an Action and make sure your reducers respond to the action and set the new state as per your application requirements.