javascriptpythontypescriptfirebasegoogle-cloud-functions

How to use cloud functions to create a document in Firebase Cloud Storage


I have created a Python cloud function to create a new document in Cloud Storage. It works well with firebase emulators:start, but I get an error when trying to call it from my application:

cloud-function.ts:20 Error executing cloud function upload_html_page FirebaseError: unauthenticated

I have set my scurity rules to allow read, write: true in Firebase Cloud Storage.

My cloud function is:

@https_fn.on_request()
def upload_html_page(req: https_fn.Request) -> https_fn.Response:
    """Store an entire recorded HTML page."""
    try:
        # Expecting the HTML content to be provided in the request body
        data = req.get_json().get('data', {})
        print(f"Received data: {data}")  # Log received data

        html_content = data.get("htmlAsString")
        documentId = data.get('documentId')
        actionId = data.get('actionId')
        eventId = data.get('eventId')

        storage_client = gcs_storage.Client()

        # Reference to your bucket
        bucket = storage_client.bucket('***SECRET FOR STACK OVERFLOW***')

        # Create a new blob and upload the file's content.
        blob = bucket.blob(documentId + "/" + eventId + "_" + actionId)

        # Upload the file to Firebase Storage
        blob.upload_from_string(html_content)

        return https_fn.Response(status=200)
    except Exception as e:
        return https_fn.Response(f"Error processing HTML content: {str(e)}", status=500)

And I call it in typescript with:

import { getApp } from './get-app';
import { getFunctions, httpsCallable } from 'firebase/functions';

const functions = getFunctions(getApp());
const payload: { [key: string]: any } = {};
            payload["htmlAsString"] = response.htmlAsString;
            payload["documentId"] = documentId;
            payload["actionId"] = actionId;
            payload["eventId"] = eventId;
const cloudFunction = httpsCallable(functions, "upload_html_page");
    try {
        const result = await cloudFunction(payload);
        return result.data;
    } catch (ex) {
        console.error("Error executing cloud function", name, ex);
        return null;
    }

I am connected to a FireBase account in my application when I do the call.

Is there anything I must configure in the Firebase console ?


Solution

  • You're mixing up callable and HTTP type functions. Your Cloud Function is a normal HTTP type function annotated with @https_fn.on_request(), but your client code is trying to invoke a callable function. These two types of functions are not compatible with each other.

    See: How do Callable Cloud Functions compare to HTTP functions?

    You either need to re-write your function as a callable type function annotated with @https_fn.on_call() (note that it has a different API with different returned results), or you need to use a normal HTTP library to invoke your function from the client. See the linked documentation at the top of this answer for examples and details.