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":
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?