React Native WebView Invoke onMessage

<WebView
source={{ uri: url1 }}
style={{ flex: 1 }}
onMessage={this.onMessage}
/>

url1 will redirect to url2 after completing a payment. The question is how can invoke onMessage in url2? I tried window.postMessage in url2, but that did not invoke the Webview onMessage that is on the client-side. What am I missing here?

The html in my url2 is like following:

<DOCTYPE html>
<html>
  <body>
    <div>
      <button id="event">Go Back</button>
    </div>
  </body>
  <script>
    document.getElementById('event').addEventListener('click', function() {
      window.postMessage('string', '*')}, false);
  </script>
</html>
3 Likes

I need this solutions too… :pensive:

Security Warning: Currently, onMessage and postMessage do not allow webview , but will still call pre-existing values of postMessage.

It works for me.

I created a snack based on the example code from the react-native-webview docs:

See README.md in the snack for the contents of url2 that I just hosted using serve.

Thanks for the feedback.

My code doesn’t have the HTML part…follows below as part of the page reference.

 <WebView
          originWhitelist={['*']}
          allowsInlineMediaPlayback
          javaScriptEnabled
          scalesPageToFit
          mediaPlaybackRequiresUserAction={false}
          startInLoadingState
          javaScriptEnabledAndroid
          useWebkit
          onLoad={webViewLoaded}
          ref={WEBVIEW}
          useWebKit={true}
          onNavigationStateChange={onNavigationStateChange}
          source={{ uri: "https://socialranking.bubbleapps.io/version-test/" }}
        />

the script will come from this site (uri) call on the script

window.ReactNativeWebView.postMessage("message example");

this webview is not complete yet…But I followed many examples and none of them worked.

You need an onMessage event handler.

See this Snack:

I sent the old code…below the current one that already exists onMessage

import React, { Component, useEffect, useState, useRef } from "react";
import {Platform, Dimensions, SafeAreaView, View, Image, Alert} from "react-native";
import { WebView } from "react-native-webview";
import Constants from "expo-constants";
import NetInfo from "@react-native-community/netinfo";
import { Audio } from 'expo-av';
import * as Notifications from 'expo-notifications';
export * from "expo-notifications";
import { Camera } from "expo-camera";

const BACKGROUND_COLOR = "#000000";
const DEVICE_WIDTH = Dimensions.get("window").width;
const DEVICE_HEIGHT = Dimensions.get("window").height;
const ANDROID_BAR_HEIGHT = Platform.OS === "android" ? Constants.statusBarHeight : 0;
const sound = new Audio.Sound();

/*
///// Notification

Notifications.requestPermissionsAsync()

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});
*/

///// Sound intro
try {
  const {
    sound: soundObject,
    status,
  } = Audio.Sound.createAsync(require('./assets/open.mp3'), { shouldPlay: true });
  // playing
} catch (error) {
  // if error
}

///// Get permission of cam
Camera.requestPermissionsAsync();

export class message extends Component {
  
  onMessage( event ) {
    Alert.alert(
      'On Message',
      event.nativeEvent.data,
      [
        {text: 'OK'},
      ],
      { cancelable: true }
    )
  }
}



export default function App(props) {

  const WEBVIEW = useRef()
  const [loading, setLoading] = useState(true)
  const [backButtonEnabled, setBackButtonEnabled] = useState(false)
  const [isConnected, setConnected] = useState(true)


  /*
    Notifications.scheduleNotificationAsync({
      content: {
        title: "GoMexico 📬",
        body: 'Nova mensagem',
        data: { data: 'goes here' },
      },
      trigger: { seconds: 1 },
    });
    
  */  

  // Webview content loadeds
  function webViewLoaded() {
    setLoading(false)
  };

  // Webview navigation state change
  function onNavigationStateChange(navState) {
    setBackButtonEnabled(navState.canGoBack)
  };

  useEffect(() => {
    // Subscribe for net state
    const netInfroSubscribe = NetInfo.addEventListener((state) => {
      setConnected(state.isConnected)
      if (!state.isConnected) {
        alert("Sem ConexĂŁo");
      }
    });

    // Clean up
    return netInfroSubscribe
  }, [])

  return (
    <SafeAreaView
      style={{
        flex: 1,
        backgroundColor: BACKGROUND_COLOR,
      }}
    >
      <View
        style={{
          height: ANDROID_BAR_HEIGHT,
          backgroundColor: BACKGROUND_COLOR,
        }}
      ></View>
      {(loading || !isConnected) && (
        <View
          style={{
            backgroundColor: BACKGROUND_COLOR,
            position: "absolute",
            top: 0,
            left: 0,
            zIndex: 10,
            width: DEVICE_WIDTH,
            height: DEVICE_HEIGHT + ANDROID_BAR_HEIGHT,
            flex: 1,
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Image source={require("./assets/icon.png")}></Image>
        </View>
      )}
      {isConnected && (
        <WebView
          originWhitelist={['*']}
          allowsInlineMediaPlayback
          javaScriptEnabled
          scalesPageToFit
          mediaPlaybackRequiresUserAction={false}
          startInLoadingState
          javaScriptEnabledAndroid
          useWebkit
          onLoad={webViewLoaded}
          ref={WEBVIEW}
          onMessage={this.onMessage}
          useWebKit={true}
          onNavigationStateChange={onNavigationStateChange}
          source={{ uri: "https://socialranking.bubbleapps.io/version-test/" }}
        />
      )}
    </SafeAreaView>
    
  );
  
}

OK, so if you try my Snack with Expo Go, does it work for you?
If not, could you see what’s different between your code and my code that might be causing the problem?
Does the postMessage() code at the source actually get called?
Or maybe you could provide a URL to a very simple page that does a postMessage() without having to login or anything like that?

Basically, I provided two examples that work for me. My second example looks to me like your code. So please can you see whether my code works when you test it, and what the differences might be between my code and your code. Or provide a simple test that does not work (e.g. on Snack) that I can try myself.

wodin
I’m sorry for the delay in replying…

yes it worked perfectly, I made a modification to the js script.

I can send push notifications native from a web application via webview

1 Like