Human-in-the-Loop-Workflow mit Callbacks erstellen


In dieser Anleitung erfahren Sie, wie Sie einen Übersetzungsworkflow erstellen, der auf Sie – den Human in the Loop – und Ihre Eingabe wartet, und der eine Firestore-Datenbank, zwei Cloud Run-Funktionen, die Cloud Translation API und eine Webseite verbindet, die das Firebase SDK nutzt, um in Echtzeit eine Aktualisierung durchzuführen.

Mit Workflows können Sie einen Callback-Endpunkt (oder Webhook) unterstützen, der darauf wartet, dass HTTP-Anfragen an diesem Endpunkt ankommen, und die Ausführung des Workflows zu einem späteren Zeitpunkt fortsetzt. In diesem Fall wartet der Workflow auf die Ablehnung oder Validierung der Übersetzung eines Textes, aber es könnte auch ein externer Prozess sein. Weitere Informationen finden Sie unter Mit Callbacks warten.

Architektur

In dieser Anleitung wird eine Webanwendung erstellt, die Folgendes ermöglicht:

  1. Geben Sie auf der Übersetzungswebseite den Text ein, der vom Englischen ins Französische übersetzt werden soll. Klicken Sie auf Übersetzen.
  2. Über die Webseite wird eine Cloud Run-Funktion aufgerufen, die die Ausführung des Workflows startet. Der zu übersetzende Text wird als Parameter sowohl an die Funktion als auch an den Workflow übergeben.
  3. Der Text wird in einer Cloud Firestore-Datenbank gespeichert. Die Cloud Translation API wird aufgerufen. Die zurückgegebene Übersetzung wird in der Datenbank gespeichert. Die Webanwendung wird mit Firebase Hosting bereitgestellt und in Echtzeit aktualisiert, um den übersetzten Text anzuzeigen.
  4. Im Schritt create_callback des Workflows wird eine Callback-Endpunkt-URL erstellt, die auch in der Firestore-Datenbank gespeichert wird. Auf der Webseite werden jetzt sowohl die Schaltfläche Validieren als auch Ablehnen angezeigt.
  5. Der Workflow wird jetzt pausiert und wartet auf eine explizite HTTP-POST-Anfrage an die URL des Callback-Endpunkts.
  6. Sie können entscheiden, ob Sie die Übersetzung validieren oder ablehnen möchten. Wenn Sie auf eine Schaltfläche klicken, wird eine zweite Cloud Run-Funktion aufgerufen, die wiederum den vom Workflow erstellten Callback-Endpunkt aufruft und den Genehmigungsstatus übergibt. Der Workflow wird fortgesetzt und der Genehmigungsstatus true oder false wird in der Firestore-Datenbank gespeichert.

Dieses Diagramm bietet eine Übersicht über den Prozess:

Workflow mit Callback

Ziele

  • Webanwendung bereitstellen
  • Firestore-Datenbank zum Speichern von Übersetzungsanfragen erstellen
  • Cloud Run-Funktionen zum Ausführen des Workflows bereitstellen
  • Workflow zur Orchestrierung des gesamten Prozesses bereitstellen und ausführen

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Vorbereitung

Von Ihrer Organisation definierte Sicherheitsbeschränkungen verhindern möglicherweise, dass die folgenden Schritte ausgeführt werden. Informationen zur Fehlerbehebung finden Sie unter Anwendungen in einer eingeschränkten Google Cloud-Umgebung entwickeln.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the App Engine, Cloud Build, Cloud Run functions, Firestore, Translation, and Workflows APIs:

    gcloud services enable appengine.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com firestore.googleapis.com translate.googleapis.com workflows.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the App Engine, Cloud Build, Cloud Run functions, Firestore, Translation, and Workflows APIs:

    gcloud services enable appengine.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com firestore.googleapis.com translate.googleapis.com workflows.googleapis.com
  12. Aktualisieren Sie die Google Cloud CLI-Komponenten:
    gcloud components update
  13. Melden Sie sich mit Ihrem -Konto an:
    gcloud auth login
  14. Legen Sie die Projekt-ID und den Standardspeicherort fest, die in dieser Anleitung verwendet werden:
    export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    export REGION=REGION
    gcloud config set workflows/location ${REGION}

    Ersetzen Sie Folgendes:

    • PROJECT_ID ist Ihre Google Cloud-Projekt-ID. Sie finden Ihre Projekt-ID auf der Willkommensseite der Google Cloud Console.
    • REGION: den unterstützten Workflows-Speicherort Ihrer Wahl.

Erste Cloud Run-Funktion bereitstellen

Diese Cloud Run-Funktion startet die Ausführung des Workflows. Der zu übersetzende Text wird als Parameter sowohl an die Funktion als auch an den Workflow übergeben.

  1. Erstellen Sie ein Verzeichnis namens callback-translation mit den Unterverzeichnissen invokeTranslationWorkflow, translationCallbackCall und public:

    mkdir -p ~/callback-translation/{invokeTranslationWorkflow,translationCallbackCall,public}
  2. Wechseln Sie in das Verzeichnis invokeTranslationWorkflow:

    cd ~/callback-translation/invokeTranslationWorkflow
  3. Erstellen Sie eine Textdatei mit dem Dateinamen index.js, die den folgenden Node.js-Code enthält:

    const cors = require('cors')({origin: true});
    const {ExecutionsClient} = require('@google-cloud/workflows');
    const client = new ExecutionsClient();
    
    exports.invokeTranslationWorkflow = async (req, res) => {
      cors(req, res, async () => {
        const text = req.body.text;
        console.log(`Translation request for "${text}"`);
    
        const PROJECT_ID = process.env.PROJECT_ID;
        const CLOUD_REGION = process.env.CLOUD_REGION;
        const WORKFLOW_NAME = process.env.WORKFLOW_NAME;
    
        const execResponse = await client.createExecution({
          parent: client.workflowPath(PROJECT_ID, CLOUD_REGION, WORKFLOW_NAME),
          execution: {
            argument: JSON.stringify({text})
          }
        });
        console.log(`Translation workflow execution request: ${JSON.stringify(execResponse)}`);
    
        const execName = execResponse[0].name;
        console.log(`Created translation workflow execution: ${execName}`);
    
        res.set('Access-Control-Allow-Origin', '*');
        res.status(200).json({executionId: execName});
      });
    };
  4. Erstellen Sie eine Textdatei mit dem Dateinamen package.json, die die folgenden npm-Metadaten enthält:

    {
      "name": "launch-translation-workflow",
      "version": "0.0.1",
      "dependencies": {
        "@google-cloud/workflows": "^1.2.5",
        "cors": "^2.8.5"
      }
    }
    
  5. Stellen Sie die Funktion mit einem HTTP-Trigger bereit und lassen Sie nicht authentifizierten Zugriff zu:

    gcloud functions deploy invokeTranslationWorkflow \
    --region=${REGION} \
    --runtime nodejs14 \
    --entry-point=invokeTranslationWorkflow \
    --set-env-vars PROJECT_ID=${GOOGLE_CLOUD_PROJECT},CLOUD_REGION=${REGION},WORKFLOW_NAME=translation_validation \
    --trigger-http \
    --allow-unauthenticated

    Die Bereitstellung der Funktion kann einige Minuten dauern. Alternativ können Sie die Funktion über die Cloud Run Functions-Oberfläche in der Google Cloud Console bereitstellen.

  6. Nachdem die Funktion bereitgestellt wurde, können Sie das Attribut httpsTrigger.url bestätigen:

    gcloud functions describe invokeTranslationWorkflow

    Notieren Sie sich die zurückgegebene URL, damit Sie sie in einem späteren Schritt verwenden können.

Zweite Cloud Run-Funktion bereitstellen

Diese Cloud Run-Funktion stellt eine HTTP-POST-Anfrage an den vom Workflow erstellten Callback-Endpunkt und übergibt einen Genehmigungsstatus, der angibt, ob die Übersetzung validiert oder abgelehnt wurde.

  1. Wechseln Sie in das Verzeichnis translationCallbackCall:

    cd ../translationCallbackCall
  2. Erstellen Sie eine Textdatei mit dem Dateinamen index.js, die den folgenden Node.js-Code enthält:

    const cors = require('cors')({origin: true});
    const fetch = require('node-fetch');
    
    exports.translationCallbackCall = async (req, res) => {
      cors(req, res, async () => {
        res.set('Access-Control-Allow-Origin', '*');
    
        const {url, approved} = req.body;
        console.log("Approved? ", approved);
        console.log("URL = ", url);
        const {GoogleAuth} = require('google-auth-library');
        const auth = new GoogleAuth();
        const token = await auth.getAccessToken();
        console.log("Token", token);
    
        try {
          const resp = await fetch(url, {
              method: 'POST',
              headers: {
                  'accept': 'application/json',
                  'content-type': 'application/json',
                  'authorization': `Bearer ${token}`
              },
              body: JSON.stringify({ approved })
          });
          console.log("Response = ", JSON.stringify(resp));
    
          const result = await resp.json();
          console.log("Outcome = ", JSON.stringify(result));
    
          res.status(200).json({status: 'OK'});
        } catch(e) {
          console.error(e);
    
          res.status(200).json({status: 'error'});
        }
      });
    };
  3. Erstellen Sie eine Textdatei mit dem Dateinamen package.json, die die folgenden npm-Metadaten enthält:

    {
      "name": "approve-translation-workflow",
      "version": "0.0.1",
      "dependencies": {
        "cors": "^2.8.5",
        "node-fetch": "^2.6.1",
        "google-auth-library": "^7.1.1"
      }
    }
    
  4. Stellen Sie die Funktion mit einem HTTP-Trigger bereit und lassen Sie nicht authentifizierten Zugriff zu:

    gcloud functions deploy translationCallbackCall \
    --region=${REGION} \
    --runtime nodejs14 \
    --entry-point=translationCallbackCall \
    --trigger-http \
    --allow-unauthenticated

    Die Bereitstellung der Funktion kann einige Minuten dauern. Alternativ können Sie die Funktion über die Cloud Run Functions-Oberfläche in der Google Cloud Console bereitstellen.

  5. Nachdem die Funktion bereitgestellt wurde, können Sie das Attribut httpsTrigger.url bestätigen:

    gcloud functions describe translationCallbackCall

    Notieren Sie sich die zurückgegebene URL, damit Sie sie in einem späteren Schritt verwenden können.

Workflow bereitstellen

Ein Workflow besteht aus einer Reihe von Schritten, die mit der Workflows-Syntax beschrieben werden. Diese kann entweder im YAML- oder JSON-Format geschrieben werden. Dies ist die Definition des Workflows. Nachdem Sie einen Workflow erstellt haben, stellen Sie ihn bereit, um ihn für die Ausführung verfügbar zu machen.

  1. Wechseln Sie in das Verzeichnis callback-translation:

    cd ..
  2. Erstellen Sie eine Textdatei mit dem Dateinamen translation-validation.yaml und folgendem Inhalt:

    main:
        params: [translation_request]
        steps:
            - log_request:
                call: sys.log
                args:
                    text: ${translation_request}
            - vars:
                assign:
                    - exec_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_EXECUTION_ID")}
                    - text_to_translate: ${translation_request.text}
                    - database_root: ${"projects/" + sys.get_env("GOOGLE_CLOUD_PROJECT_ID") + "/databases/(default)/documents/translations/"}
            - log_translation_request:
                call: sys.log
                args:
                    text: ${text_to_translate}
    
            - store_translation_request:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['text']
                    body:
                        fields:
                            text:
                                stringValue: ${text_to_translate}
                result: store_translation_request_result
    
            - translate:
                call: googleapis.translate.v2.translations.translate
                args:
                    query:
                        q: ${text_to_translate}
                        target: "FR"
                        format: "text"
                        source: "EN"
                result: translation_result
            - assign_translation:
                assign:
                    - translation: ${translation_result.data.translations[0].translatedText} 
            - log_translation_result:
                call: sys.log
                args:
                    text: ${translation}
    
            - store_translated_text:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['translation']
                    body:
                        fields:
                            translation:
                                stringValue: ${translation}
                result: store_translation_request_result   
    
            - create_callback:
                call: events.create_callback_endpoint
                args:
                    http_callback_method: "POST"
                result: callback_details
            - log_callback_details:
                call: sys.log
                args:
                    text: ${callback_details}
    
            - store_callback_details:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['callback']
                    body:
                        fields:
                            callback:
                                stringValue: ${callback_details.url}
                result: store_callback_details_result
    
            - await_callback:
                call: events.await_callback
                args:
                    callback: ${callback_details}
                    timeout: 3600
                result: callback_request
            - assign_approval:
                assign:
                    - approved: ${callback_request.http_request.body.approved}
    
            - store_approval:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['approved']
                    body:
                        fields:
                            approved:
                                booleanValue: ${approved}
                result: store_approval_result
    
            - return_outcome:
                return:
                    text: ${text_to_translate}
                    translation: ${translation}
                    approved: ${approved}
  3. Nachdem Sie den Workflow erstellt haben, können Sie ihn bereitstellen, aber nicht den Workflow ausführen:

    gcloud workflows deploy translation_validation --source=translation-validation.yaml

Webanwendung erstellen

Erstellen Sie eine Webanwendung, die eine Cloud Functions-Funktion aufruft, die die Ausführung des Workflows startet. Die Webseite wird in Echtzeit aktualisiert, um das Ergebnis der Übersetzungsanfrage anzuzeigen.

  1. Wechseln Sie in das Verzeichnis public:

    cd public
  2. Erstellen Sie eine Textdatei mit dem Dateinamen index.html, die das folgende HTML-Markup enthält. In einem späteren Schritt ändern Sie die Datei index.html und fügen die Firebase SDK-Skripts hinzu.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
    
        <title>Frenglish translation — Feature Workflows callbacks</title>
    
        <link rel="stylesheet"
            href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.42/dist/themes/base.css">
        <script type="module"
            src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.42/dist/shoelace.js"></script>
        <link rel="stylesheet" href="./style.css">
    </head>
    
    <body>
        <h1>Translate from English to French</h1>
    
        <sl-form class="form-overview">
            <sl-textarea id="text" placeholder="The quick brown fox jumps over the lazy dog."
                label="English text to translate"></sl-textarea>
            <p></p>
            <sl-button id="translateBtn" type="primary">Translate</sl-button>
            <p></p>
            <sl-alert id="translation" type="primary">
                Le rapide renard brun saute au dessus du chien paresseux.
            </sl-alert>
            <p></p>
            <div id="buttonRow" style="display: none;">
                <sl-button id="validateBtn" type="success">Validate</sl-button>
                <sl-button id="rejectBtn" type="danger">Reject</sl-button>
            </div>
            <p></p>
            <sl-alert id="validationAlert" type="success">
                <sl-icon slot="icon" name="check2-circle"></sl-icon>
                <strong>The translation has been validated</strong><br>
                Glad that you liked our translation! We'll save it in our database.
            </sl-alert>
            <sl-alert id="rejectionAlert" type="danger">
                <sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
                <strong>The translation has been rejected</strong><br>
                A pity the translation isn't good! We'll do better next time!
            </sl-alert>
            <p></p>
            <sl-button id="newBtn" style="display: none;" type="primary">New translation</sl-button>
        </sl-form>
    
        <script src="https://www.gstatic.com/firebasejs/8.6.3/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/8.6.3/firebase-firestore.js"></script>
    
        <script>
            var firebaseConfig = {
                apiKey: "XXXX",
                authDomain: "XXXX",
                projectId: "XXXX",
                storageBucket: "XXXX",
                messagingSenderId: "XXXX",
                appId: "XXXX",
                measurementId: "XXXX"
            };
            // Initialize Firebase
            firebase.initializeApp(firebaseConfig);
        </script>
        <script src="./script.js" type="module"></script>
    </body>
    
    </html>
    
  3. Erstellen Sie eine Textdatei mit dem Dateinamen script.js, die den folgenden JavaScript-Code enthält:

    document.addEventListener("DOMContentLoaded", async function (event) {
        const textArea = document.getElementById("text");
        textArea.focus();
    
        const newBtn = document.getElementById("newBtn");
        newBtn.addEventListener("sl-focus", event => {
            event.target.blur();
            window.location.reload();
        });
    
        const translationAlert = document.getElementById("translation");
        const buttonRow = document.getElementById("buttonRow");
    
        var callbackUrl = "";
    
        const validationAlert = document.getElementById("validationAlert");
        const rejectionAlert = document.getElementById("rejectionAlert");
        const validateBtn = document.getElementById("validateBtn");
        const rejectBtn = document.getElementById("rejectBtn");
    
        const translateBtn = document.getElementById("translateBtn");
        translateBtn.addEventListener("sl-focus", async event => {
            event.target.disabled = true;
            event.target.loading = true;
            textArea.disabled = true;
    
            console.log("Text to translate = ", textArea.value);
    
            const fnUrl = UPDATE_ME;
    
            try {
                console.log("Calling workflow executor function...");
                const resp = await fetch(fnUrl, {
                    method: "POST",
                    headers: {
                        "accept": "application/json",
                        "content-type": "application/json"
                    },
                    body: JSON.stringify({ text: textArea.value })
                });
                const executionResp = await resp.json();
                const executionId = executionResp.executionId.slice(-36);
                console.log("Execution ID = ", executionId);
    
                const db = firebase.firestore();
                const translationDoc = db.collection("translations").doc(executionId);
    
                var translationReceived = false;
                var callbackReceived =  false;
                var approvalReceived = false;
                translationDoc.onSnapshot((doc) => {
                    console.log("Firestore update", doc.data());
                    if (doc.data()) {
                        if ("translation" in doc.data()) {
                            if (!translationReceived) {
                                console.log("Translation = ", doc.data().translation);
                                translationReceived = true;
                                translationAlert.innerText = doc.data().translation;
                                translationAlert.open = true;
                            }
                        }
                        if ("callback" in doc.data()) {
                            if (!callbackReceived) {
                                console.log("Callback URL = ", doc.data().callback);
                                callbackReceived = true;
                                callbackUrl = doc.data().callback;
                                buttonRow.style.display = "block";
                            }
                        }
                        if ("approved" in doc.data()) {
                            if (!approvalReceived) {
                                const approved = doc.data().approved;
                                console.log("Approval received = ", approved);
                                if (approved) {
                                    validationAlert.open = true;
                                    buttonRow.style.display = "none";
                                    newBtn.style.display = "inline-block";   
                                } else {
                                    rejectionAlert.open = true;
                                    buttonRow.style.display = "none";
                                    newBtn.style.display = "inline-block";
                                }
                                approvalReceived = true;
                            }
                        }
                    }
                });
            } catch (e) {
                console.log(e);
            }
            event.target.loading = false;
        });
    
        validateBtn.addEventListener("sl-focus", async event => {
            validateBtn.disabled = true;
            rejectBtn.disabled = true;
            validateBtn.loading = true;
            validateBtn.blur();
    
            // call callback
            await callCallbackUrl(callbackUrl, true);
        });
    
        rejectBtn.addEventListener("sl-focus", async event => {
            rejectBtn.disabled = true;
            validateBtn.disabled = true;
            rejectBtn.loading = true;
            rejectBtn.blur();
    
            // call callback
            await callCallbackUrl(callbackUrl, false);
        });
    
    });
    
    async function callCallbackUrl(url, approved) {
        console.log("Calling callback URL with status = ", approved);
    
        const fnUrl = UPDATE_ME;
        try {
            const resp = await fetch(fnUrl, {
                method: "POST",
                headers: {
                    "accept": "application/json",
                    "content-type": "application/json"
                },
                body: JSON.stringify({ url, approved })
            });
            const result = await resp.json();
            console.log("Callback answer = ", result);
        } catch(e) {
            console.log(e);
        }
    }
  4. Bearbeiten Sie die Datei script.js und ersetzen Sie die Platzhalter UPDATE_ME durch die zuvor notierten Cloud Run-Funktions-URLs.

    1. Ersetzen Sie in der Methode translateBtn.addEventListener const fnUrl = UPDATE_ME; durch:

      const fnUrl = "https://REGION-PROJECT_ID.cloudfunctions.net/invokeTranslationWorkflow";

    2. Ersetzen Sie in der Funktion callCallbackUrl const fnUrl = UPDATE_ME; durch:

      const fnUrl = "https://REGION-PROJECT_ID.cloudfunctions.net/translationCallbackCall";

  5. Erstellen Sie eine Textdatei mit dem Dateinamen style.css, die die folgenden kaskadierenden Stile enthält:

    * {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    }
    
    body {
        margin: 20px;
    }
    
    h1, h2, h3, h4 {
        color: #0ea5e9;
    }
    

Firebase zu meiner Web-App hinzufügen

In dieser Anleitung werden die HTML-Seite, das JavaScript-Script und das CSS-Stylesheet mit Firebase Hosting als statische Assets bereitgestellt. Sie können aber auch an anderer Stelle gehostet und zu Testzwecken lokal auf Ihrem eigenen Computer bereitgestellt werden.

Firebase-Projekt erstellen

Bevor Sie Firebase zu Ihrer Anwendung hinzufügen können, müssen Sie ein Firebase-Projekt erstellen, um eine Verbindung zu Ihrer Anwendung herzustellen.

  1. Klicken Sie in der Firebase Console auf Projekt erstellen und wählen Sie Ihr vorhandenes Google Cloud-Projekt aus dem Drop-down-Menü aus, um Firebase-Ressourcen zu diesem Projekt hinzuzufügen.

  2. Klicken Sie auf Weiter, bis Sie die Option zum Hinzufügen von Firebase sehen.

  3. Überspringen Sie die Einrichtung von Google Analytics für Ihr Projekt.

  4. Klicken Sie auf Firebase hinzufügen.

Firebase stellt automatisch Ressourcen für Ihr Firebase-Projekt bereit. Nach Abschluss des Vorgangs werden Sie zur Übersichtsseite für Ihr Projekt in der Firebase Console weitergeleitet.

App bei Firebase registrieren

Nachdem Sie ein Firebase-Projekt haben, können Sie Ihre Webanwendung hinzufügen.

  1. Klicken Sie in der Mitte der Projektübersicht auf das Symbol Web (</>), um den Einrichtungsworkflow zu starten.

  2. Geben Sie einen Alias für die Anwendung ein.

    Dieser ist nur in der Firebase Console sichtbar.

  3. Überspringen Sie die Einrichtung von Firebase Hosting.

  4. Klicken Sie auf App registrieren und fahren Sie mit der Konsole fort.

Cloud Firestore aktivieren

Die Webanwendung verwendet Cloud Firestore, um Daten zu empfangen und zu speichern. Sie müssen Cloud Firestore aktivieren.

  1. Klicken Sie im Abschnitt Build in der Firebase Console auf Firestore-Datenbank.

    Möglicherweise müssen Sie zuerst den linken Navigationsbereich erweitern, um den Abschnitt Build einzublenden.

  2. Klicken Sie im Cloud Firestore-Bereich auf Datenbank erstellen.

  3. Wählen Sie Im Testmodus starten mit einer Sicherheitsregel wie der folgenden aus:

    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
      match /{document=**} {
        allow read, write;
      }
    }
    }
  4. Klicken Sie auf Weiter, nachdem Sie den Haftungsausschluss zu den Sicherheitsregeln gelesen haben.

  5. Legen Sie den Speicherort für Cloud Firestore-Daten fest. Sie können die Standardeinstellung übernehmen oder eine Region in Ihrer Nähe auswählen.

  6. Klicken Sie auf Aktivieren, um Firestore bereitzustellen.

Firebase SDK hinzufügen und Firebase initialisieren

Firebase stellt JavaScript-Bibliotheken für die meisten Firebase-Produkte bereit. Bevor Sie Firebase Hosting verwenden, müssen Sie die Firebase SDKs Ihrer Webanwendung hinzufügen.

  1. Zum Initialisieren von Firebase in Ihrer Anwendung müssen Sie die Firebase-Projektkonfiguration Ihrer Anwendung angeben.
    1. Rufen Sie in der Firebase Console die Projekteinstellungen auf.
    2. Wählen Sie im Bereich Meine Apps Ihre App aus.
    3. Wenn Sie Firebase SDK-Bibliotheken aus dem CDN laden möchten, wählen Sie im Bereich SDK-Einrichtung und -Konfiguration die Option CDN aus.
    4. Kopieren Sie das Snippet in die Datei index.html unter dem <body>-Tag und ersetzen Sie die Platzhalterwerte für XXXX.
  2. Installieren Sie das Firebase JavaScript SDK.

    1. Wenn Sie noch keine package.json-Datei haben, erstellen Sie eine mit dem folgenden Befehl im Verzeichnis callback-translation:

      npm init
    2. Installieren Sie das npm-Paket firebase und speichern Sie es in der package.json-Datei:

      npm install --save firebase

Projekt initialisieren und bereitstellen

Sie müssen Ihr Projekt initialisieren, um Ihre lokalen Projektdateien mit Ihrem Firebase-Projekt zu verbinden. Sie können dann Ihre Webanwendung bereitstellen.

  1. Führen Sie im Verzeichnis callback-translation den folgenden Befehl aus:

    firebase init
  2. Wählen Sie die Option Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys aus.

  3. Verwenden Sie ein vorhandenes Projekt und geben Sie Ihre Projekt-ID ein.

  4. Übernehmen Sie public als standardmäßiges öffentliches Stammverzeichnis.

  5. Konfigurieren Sie eine einseitige App.

  6. Überspringen Sie die Einrichtung automatischer Builds und Bereitstellungen mit GitHub.

  7. Geben Sie bei der Eingabeaufforderung File public/index.html already exists. Overwrite? Nein ein.

  8. Wechseln Sie in das Verzeichnis public:

    cd public
  9. Führen Sie im Verzeichnis public den folgenden Befehl aus, um das Projekt auf Ihrer Website bereitzustellen:

    firebase deploy --only hosting

Webanwendung lokal testen

Mit Firebase Hosting können Sie Änderungen lokal ansehen und testen und mit emulierten Backend-Projektressourcen interagieren. Wenn Sie firebase serve verwenden, interagiert Ihre Anwendung mit einem emulierten Backend für Ihre Hosting-Inhalte und Ihre Konfiguration, aber Ihr echtes Backend tut dies für alle anderen Projektressourcen. Für diese Anleitung können Sie firebase serve verwenden. Dies wird jedoch nicht empfohlen, wenn Sie umfangreichere Tests durchführen.

  1. Führen Sie im Verzeichnis public den folgenden Befehl aus:

    firebase serve
  2. Öffnen Sie Ihre Webanwendung unter der zurückgegebenen lokalen URL (in der Regel http://localhost:5000).

  3. Geben Sie Text in Englisch ein und klicken Sie dann auf Übersetzen.

    Eine Übersetzung des Textes auf Französisch sollte angezeigt werden.

  4. Sie können jetzt auf Validieren oder Ablehnen klicken.

    In der Firestore-Datenbank können Sie den Inhalt prüfen. Diese sollten in etwa so aussehen:

    approved: true
    callback: "https://workflowexecutions.googleapis.com/v1/projects/26811016474/locations/us-central1/workflows/translation_validation/executions/68bfce75-5f62-445f-9cd5-eda23e6fa693/callbacks/72851c97-6bb2-45e3-9816-1e3dcc610662_1a16697f-6d90-478d-9736-33190bbe222b"
    text: "The quick brown fox jumps over the lazy dog."
    translation: "Le renard brun rapide saute par-dessus le chien paresseux."
    

    Der Status approved lautet true oder false, je nachdem, ob Sie die Übersetzung validieren oder ablehnen.

Das war's auch schon! Sie haben einen Human-in-the-Loop-Workflow erstellt, der Workflow-Callbacks verwendet.

Bereinigen

Wenn Sie ein neues Projekt für diese Anleitung erstellt haben, löschen Sie das Projekt. Wenn Sie ein vorhandenes Projekt verwendet haben und es beibehalten möchten, ohne die Änderungen in dieser Anleitung hinzuzufügen, löschen Sie die für die Anleitung erstellten Ressourcen.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.

So löschen Sie das Projekt:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Anleitungsressourcen löschen

  1. Entfernen Sie die gcloud CLI-Standardkonfiguration, die Sie während der Einrichtung der Anleitung hinzugefügt haben:

    gcloud config unset workflows/location
  2. Löschen Sie den in dieser Anleitung erstellten Workflow:

    gcloud workflows delete WORKFLOW_NAME
  3. Löschen Sie die Cloud Run-Funktionen, die Sie in dieser Anleitung erstellt haben:

    gcloud functions delete FUNCTION_NAME

    Sie können Cloud Run-Funktionen auch über die Google Cloud Console löschen.

Nächste Schritte