Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native WebView postMessage does not work

I can't get React Native WebView postMessage to work. The React Native app successfully receives the post message sendt from the web app. But the web app does not receive messages sendt from the React Native app.

My simple web app

<html>  <body>    <button>Send post message from web</button>  <div>Post message log</div>  <textarea style="height: 50%; width: 100%;" readonly></textarea>    <script>  var log = document.querySelector("textarea");    document.querySelector("button").onclick = function() {      console.log("Send post message");        logMessage("Sending post message from web..");      window.postMessage("Post message from web", "*");  }    window.addEventListener("message", function(event) {      console.log("Received post message", event);        logMessage(event.data);  }, false);    function logMessage(message) {      log.append((new Date()) + " " + message + "\n");  }    </script>    </body>  </html>

This web app is hosted at: https://popping-heat-6062.firebaseapp.com/

My simple React Native app

import React, {Component} from "react"; import {AppRegistry, Text, View, TouchableHighlight, WebView} from "react-native";  export default class WevViewApp extends Component {      constructor( props ) {         super( props );          this.webView = null;     }      onMessage( event ) {         console.log( "On Message", event.nativeEvent.data );     }      sendPostMessage() {         console.log( "Sending post message" );         this.webView.postMessage( "Post message from react native" );     }      render() {         return (             <View style={{flex: 1}}>                 <TouchableHighlight style={{padding: 10, backgroundColor: 'blue', marginTop: 20}} onPress={() => this.sendPostMessage()}>                     <Text style={{color: 'white'}}>Send post message from react native</Text>                 </TouchableHighlight>                 <WebView                     style={{flex: 1}}                     source={{uri: 'https://popping-heat-6062.firebaseapp.com'}}                     ref={( webView ) => this.webView = webView}                     onMessage={this.onMessage}                 />             </View>         );     } }  AppRegistry.registerComponent( 'WevViewApp', () => WevViewApp ); 

Expected result

  1. Clicking the "Send post message from web" button sends a post message to the React Native app and is logged in debugger window
  2. Clicking the "Send post message from React Native" button sends a post message to the web app and is printed out in the web textarea

Actual result

  1. Web app successfully sends sends message to React Native app and is logged in the debugger window
  2. React Native app unsuccessfully sends message to web app and is not printed out in the web textarea

Does anyone know why the web app is not receiving the messages?

Tested with both Android and iOS.

Related documentation: https://facebook.github.io/react-native/docs/webview.html


Edit: Experienced a behaviour that may pinpoint the problem.

When testing the 'Send post message from web' button directly in a web browser the textarea logs that it has sendt the message and also that is received it's own message.

Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Sending post message from web.. Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Post message from web 

when trying the same in the WebView from the React Native app the textarea only prints out

Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Sending post message from web.. 

Does the WebView hijack the window.postMessage method and inject a custom one?

This is mentioned in the documentation:

Setting this property will inject a postMessage global into your webview, but will still call pre-existing values of postMessage.

Maybe this is false and this is where the problem is at?

like image 627
Skarbo Avatar asked Dec 15 '16 09:12

Skarbo


1 Answers

I had the same problem and fixed it by adding the event listener to the document instead of the window. Change:

window.addEventListener("message", ... 

to:

document.addEventListener("message", ... 
like image 199
JustWonder Avatar answered Sep 23 '22 02:09

JustWonder