2

I am experiencing issues regarding using the injectJavascript method to inject and call a function from the WebView component from the library: react-native-web-view. I am doing this to workaround the limitations of GUN.js. Instead of running the gun.js on react native, I am abstracting it onto a webview. (Quite hacky though.)

Enviroment:

Computer: Apple Macbook Pro 2017 - 13"

OS: Macos 13.4.1

Xcode: 14.3.1

Error message:

WARN  Error evaluating injectedJavaScript: This is possibly due to an unsupported return type. Try adding true to the end of your injectedJavaScript string. Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: window.login is not a function. (In 'window.login("John Smith", "John.Smith.1234", "*****")', 'window.login' is undefined), WKJavaScriptExceptionColumnNumber=13, WKJavaScriptExceptionSourceURL=about:blank, NSLocalizedDescription=A JavaScript exception occurred}

Package.json:

  "dependencies": {
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.13",
    "expo": "~48.0.18",
    "expo-font": "~11.1.1",
    "expo-splash-screen": "~0.18.2",
    "expo-status-bar": "~1.4.4",
    "react": "18.2.0",
    "react-native": "0.71.8",
    "react-native-get-random-values": "~1.8.0",
    "react-native-safe-area-context": "4.5.0",
    "react-native-screens": "~3.20.0",
    "react-native-uuid": "^2.0.1",
    "react-native-webview": "11.26.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/react": "~18.0.27",
    "@types/react-native": "^0.72.2",
    "@typescript-eslint/eslint-plugin": "^5.60.0",
    "@typescript-eslint/parser": "^5.60.0",
    "eslint": "~8.4.1",
    "eslint-plugin-react": "^7.32.2",
    "typescript": "^4.9.4"
  },

Anyways Here's my code: webview component:

 
  // ...
  static webViewReference = null;
  static injectScriptCallback = null;

  static injectScript(script) {
    if (GunWebView.webViewReference) {
      GunWebView.webViewReference.injectJavaScript(script);
    } else {
      GunWebView.injectScriptCallback = () => {
        GunWebView.webViewReference.injectJavaScript(script);
      };
    }
  }

  constructor(props) {
    super(props);
  }

  render() {
    return (
      <WebView
        onMessage={this.props.onMessage}
        style={this.styles.webView}
        ref={(ref) => {
          GunWebView.webViewReference = ref;
        }}
        originWhitelist={["*"]}
        javaScriptEnabled={true}
        javaScriptEnabledAndroid={true}
        source={{ html: GUN_WEB_ABSTRACTION }}
        onLoadEnd={() => {
          if (GunWebView.injectScriptCallback) {
            GunWebView.injectScriptCallback();
            GunWebView.injectScriptCallback = null;
          }
        }}
      />
    );
  }
  // ...

GUN_WEB_ABSTRACTION:

 <script>
  // --END OF LIBRARY IMPORT--

  (function (){
  window.gun = new Gun("******************"); // Custom relay server (Unable to show)
  
  // Authentication functions:
  window.login = function (username, password, pid) {
    window.gun.user().auth(username, password, (ack) => {
      window.ReactNativeWebView.postMessage(JSON.stringify({pid ...ack}));
    });
  }
  
  window.loginWithKeyPair = function (kayPair, pid) {
    window.gun.user().auth(keyPair, (ack) => {
      window.ReactNativeWebView.postMessage(JSON.stringify({pid ...ack}));
    });
  }})();
  </script>
  <!-- --END OF GUN HTML-- -->

How I am calling it:

function injectJavascript(script: string) {
  GunWebView.injectScript(script);
}

// ...

export function login(username: string, password: string) {
  // ...
  return new Promise((resolve, reject) => {
    const PID = uuid.v4();

    registerProcess(PID, (ack: any) => {
      if (ack.err) {
        reject(ack.err);
      } else {
        resolve(ack);
      }
    });

    injectJavascript(`window.login("${username}", "${password}", "${PID}");`);
     
    // ... Error handling and etc ...
  });
}

I have tried to use the injectJavascript prop and injecting the whole HTML code along with the calling logic. However, there is an error message and I am not expecting it to throw an error.

Alvin CHENG
  • 374
  • 2
  • 16
  • Never mind, I have migrated over to the web without using `react-native` as the framework, so this problem is **solved** for now. Thank you! – Alvin CHENG Jul 07 '23 at 00:23

0 Answers0