0

I have this app here: https://github.com/ChristianOConnor/google-cloudfunction-callfromreactapp. It is literally just the output of npx create-react-app google-cloudfunction-callfromreactapp --template typescript and making a few changes. I added src/api/google.ts which looks like this:

import { JWT } from "google-auth-library";
import keys from 'PATH TO KEYS HERE';

async function BasicTest() {
  const client = new JWT({
    email: keys.client_email,
    key: keys.private_key
  });
  const url = '<FUNCTION URL>';
  const res = await client.request({url});
  return res.data
  //return 'does this work'
}

export default BasicTest;

Obviously you would replace 'PATH TO KEYS HERE' with the path to your relevant service account and '<FUNCTION URL>' with the url to trigger your Google cloud function.

This is my simple Google cloud function that outputs a simple string:

import functions_framework

@functions_framework.http
def hello_http(request):
   """HTTP Cloud Function.
   Args:
       request (flask.Request): The request object.
       <https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
   Returns:
       The response text, or any set of values that can be turned into a
       Response object using `make_response`
       <https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
   """
   request_json = request.get_json(silent=True)
   request_args = request.args

   if request_json and 'name' in request_json:
       name = request_json['name']
   elif request_args and 'name' in request_args:
       name = request_args['name']
   else:
       name = 'World'
   return 'Hello {}!'.format(name)

It's a simple defualt python function that outputs a string.

I also changed the App.tsx file to this:

import logo from './logo.svg';
import './App.css';
import React, { useState } from 'react';
import BasicTest from './api/google';

function App() {
  const [resp, setResp] = useState('');
  
  async function callApi() {
    const calledData = await BasicTest().catch(console.error);
    setResp(calledData as string);
  }

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
      <div className="card">
        <button onClick={() => callApi()}>
          click this to call API
        </button>
        <p>
          {resp}
        </p>
      </div>
    </div>
  );
}

export default App;

This app works perfectly when I remove all of the google cloud function stuff and simply have google.ts return "the function ran":
enter image description here

But when I put the Google cloud function stuff back in, it fails with this error in my browser.

googleauth.js:17 Uncaught Error: Cannot find module 'child_process'
    at webpackMissingModule (googleauth.js:17:1)
    at ./node_modules/google-auth-library/build/src/auth/googleauth.js (googleauth.js:17:1)
    at options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at ./node_modules/google-auth-library/build/src/index.js (index.js:17:1)
    at options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at ./src/api/google.ts (App.tsx:42:1)

If it helps to debug this, lines 15 through 20 in googleauth.js looks like this:

Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleAuth = exports.CLOUD_SDK_CLIENT_ID = void 0;
const child_process_1 = require("child_process");
const fs = require("fs");
const gcpMetadata = require("gcp-metadata");

The error is this line const child_process_1 = require("child_process");

So how can I fix this?

ChristianOConnor
  • 820
  • 7
  • 29
  • 1
    Looks like https://stackoverflow.com/a/67033791/5529712 might do the trick? (basically the Google library is calling some native modules which are not available in the browser) – Gari Singh Dec 10 '22 at 10:59

0 Answers0