1. Przegląd
Cloud Run to usługa w pełni zarządzana, która umożliwia uruchamianie kodu bezpośrednio w skalowalnej infrastrukturze Google. W tym laboratorium dowiesz się, jak połączyć aplikację Next.js w Cloud Run z bazą danych Firestore za pomocą pakietu Node.js Admin SDK.
W tym module nauczysz się, jak:
- Utwórz bazę danych Firestore
- Wdrażanie w Cloud Run aplikacji, która łączy się z bazą danych Firestore
2. Wymagania wstępne
- Jeśli nie masz jeszcze konta Google, musisz je utworzyć.
- Używaj konta osobistego zamiast konta służbowego lub szkolnego. Konta służbowe i szkolne mogą mieć ograniczenia, które uniemożliwiają włączenie interfejsów API potrzebnych do tego ćwiczenia.
3. Konfigurowanie projektu
- Zaloguj się w konsoli Google Cloud.
- Włącz płatności w konsoli Google Cloud.
- Pod względem opłat za zasoby chmury ukończenie tego modułu powinno kosztować mniej niż 1 USD.
- Jeśli chcesz uniknąć dalszych opłat, wykonaj czynności opisane na końcu tego modułu, aby usunąć zasoby.
- Nowi użytkownicy mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
- Utwórz nowy projekt lub użyj już istniejącego.
4. Otwórz edytor Cloud Shell
- Otwórz edytor Cloud Shell.
- Jeśli terminal nie pojawi się u dołu ekranu, otwórz go:
- Kliknij menu
. - Kliknij Terminal.
- Kliknij Nowy terminal
.
- Kliknij menu
- W terminalu ustaw projekt za pomocą tego polecenia:
- Format:
gcloud config set project [PROJECT_ID] - Przykład:
gcloud config set project lab-project-id-example - Jeśli nie pamiętasz identyfikatora projektu:
- Aby wyświetlić listę wszystkich identyfikatorów projektów, użyj tego polecenia:
gcloud projects list | awk '/PROJECT_ID/{print $2}'

- Aby wyświetlić listę wszystkich identyfikatorów projektów, użyj tego polecenia:
- Format:
- Jeśli pojawi się prośba o autoryzację, kliknij Autoryzuj, aby przejść dalej.

- Powinien wyświetlić się ten komunikat:
Jeśli widzisz symbolUpdated property [core/project].
WARNINGi pojawia się pytanieDo you want to continue (Y/N)?, prawdopodobnie identyfikator projektu został wpisany nieprawidłowo. NaciśnijN, a następnieEnteri spróbuj ponownie uruchomić poleceniegcloud config set project.
5. Włącz interfejsy API
W terminalu włącz interfejsy API:
gcloud services enable \
firestore.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Jeśli pojawi się prośba o autoryzację, kliknij Autoryzuj, aby przejść dalej. 
Wykonanie tego polecenia może potrwać kilka minut, ale powinno ostatecznie wyświetlić komunikat o sukcesie podobny do tego:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
6. Tworzenie bazy danych Firestore
- Uruchom polecenie
gcloud firestore databases create, aby utworzyć bazę danych Firestore.gcloud firestore databases create --location=nam5
7. Przygotowywanie aplikacji
Przygotuj aplikację Next.js, która odpowiada na żądania HTTP.
- Aby utworzyć nowy projekt Next.js o nazwie
task-app, użyj tego polecenia:npx --yes create-next-app@15 task-app \ --ts \ --eslint \ --tailwind \ --no-src-dir \ --turbopack \ --app \ --no-import-alias - Przejdź do katalogu
task-app:cd task-app
- Zainstaluj
firebase-admin, aby korzystać z bazy danych Firestore.npm install firebase-admin
- Otwórz plik
actions.tsw edytorze Cloud Shell: U góry ekranu powinien pojawić się pusty plik. W tym miejscu możesz edytować plikcloudshell edit app/actions.tsactions.ts.
- Skopiuj ten kod i wklej go do otwartego pliku
actions.ts:'use server' import { initializeApp, applicationDefault, getApps } from 'firebase-admin/app'; import { getFirestore } from 'firebase-admin/firestore'; const credential = applicationDefault(); // Only initialize app if it does not already exist if (getApps().length === 0) { initializeApp({ credential }); } const db = getFirestore(); const tasksRef = db.collection('tasks'); type Task = { id: string; title: string; status: 'IN_PROGRESS' | 'COMPLETE'; createdAt: number; }; // CREATE export async function addNewTaskToDatabase(newTask: string) { await tasksRef.doc().create({ title: newTask, status: 'IN_PROGRESS', createdAt: Date.now(), }); return; } // READ export async function getTasksFromDatabase() { const snapshot = await tasksRef.orderBy('createdAt', 'desc').limit(100).get(); const tasks = await snapshot.docs.map(doc => ({ id: doc.id, title: doc.data().title, status: doc.data().status, createdAt: doc.data().createdAt, })); return tasks; } // UPDATE export async function updateTaskInDatabase(task: Task) { await tasksRef.doc(task.id).set(task); return; } // DELETE export async function deleteTaskFromDatabase(taskId: string) { await tasksRef.doc(taskId).delete(); return; }
- Otwórz plik
page.tsxw edytorze Cloud Shell: U góry ekranu powinien pojawić się istniejący plik. W tym miejscu możesz edytować plikcloudshell edit app/page.tsxpage.tsx.
- Usuń dotychczasową zawartość pliku
page.tsx. - Skopiuj ten kod i wklej go do otwartego pliku
page.tsx:'use client' import React, { useEffect, useState } from "react"; import { addNewTaskToDatabase, getTasksFromDatabase, deleteTaskFromDatabase, updateTaskInDatabase } from "./actions"; type Task = { id: string; title: string; status: 'IN_PROGRESS' | 'COMPLETE'; createdAt: number; }; export default function Home() { const [newTaskTitle, setNewTaskTitle] = useState(''); const [tasks, setTasks] = useState<Task[]>([]); async function getTasks() { const updatedListOfTasks = await getTasksFromDatabase(); setTasks(updatedListOfTasks); } useEffect(() => { getTasks(); }, []); async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); await addNewTaskToDatabase(newTaskTitle); await getTasks(); setNewTaskTitle(''); }; async function updateTask(task: Task, newTaskValues: Partial<Task>) { await updateTaskInDatabase({ ...task, ...newTaskValues }); await getTasks(); } async function deleteTask(taskId: string) { await deleteTaskFromDatabase(taskId); await getTasks(); } return ( <main className="p-4"> <h2 className="text-2xl font-bold mb-4">To Do List</h2> <div className="flex mb-4"> <form onSubmit={handleSubmit} className="flex mb-8"> <input type="text" placeholder="New Task Title" value={newTaskTitle} onChange={(e) => setNewTaskTitle(e.target.value)} className="flex-grow border border-gray-400 rounded px-3 py-2 mr-2 bg-inherit" /> <button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-nowrap" > Add New Task </button> </form> </div> <table className="w-full"> <tbody> {tasks.map(function (task) { const isComplete = task.status === 'COMPLETE'; return ( <tr key={task.id} className="border-b border-gray-200"> <td className="py-2 px-4"> <input type="checkbox" checked={isComplete} onChange={() => updateTask(task, { status: isComplete ? 'IN_PROGRESS' : 'COMPLETE' })} className="transition-transform duration-300 ease-in-out transform scale-100 checked:scale-125 checked:bg-green-500" /> </td> <td className="py-2 px-4"> <span className={`transition-all duration-300 ease-in-out ${isComplete ? 'line-through text-gray-400 opacity-50' : 'opacity-100'}`} > {task.title} </span> </td> <td className="py-2 px-4"> <button onClick={() => deleteTask(task.id)} className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded float-right" > Delete </button> </td> </tr> ); })} </tbody> </table> </main> ); }
Aplikacja jest teraz gotowa do wdrożenia.
8. Wdrażanie aplikacji w Cloud Run
- Aby wdrożyć aplikację w Cloud Run, uruchom to polecenie:
gcloud run deploy helloworld \ --region=us-central1 \ --source=. - Jeśli pojawi się prośba, naciśnij
YiEnter, aby potwierdzić, że chcesz kontynuować:Do you want to continue (Y/n)? Y
Po kilku minutach aplikacja powinna podać adres URL, który możesz otworzyć.
Otwórz adres URL, aby zobaczyć działanie aplikacji. Za każdym razem, gdy otworzysz adres URL lub odświeżysz stronę, zobaczysz aplikację do zarządzania zadaniami.
9. Gratulacje
Z tego modułu dowiedziałeś(-aś) się, jak:
- Utwórz instancję Cloud SQL for PostgreSQL
- Wdrażanie aplikacji w Cloud Run, która łączy się z bazą danych Cloud SQL
Czyszczenie danych
Cloud SQL nie ma bezpłatnego poziomu i jeśli będziesz z niego korzystać, będziemy naliczać opłaty. Aby uniknąć dodatkowych opłat, możesz usunąć projekt w chmurze.
Cloud Run nie nalicza opłat, gdy usługa nie jest używana, ale może zostać pobrana należność za przechowywanie obrazu kontenera w Artifact Registry. Usunięcie projektu w chmurze spowoduje zaprzestanie naliczania opłat za wszelkie zasoby wykorzystywane w ramach tego projektu.
Jeśli chcesz, usuń projekt:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Możesz też usunąć niepotrzebne zasoby z dysku Cloud Shell. Możesz:
- Usuń katalog projektu ćwiczeń z programowania:
rm -rf ~/task-app - Ostrzeżenie! Tej czynności nie można cofnąć. Jeśli chcesz usunąć wszystko z Cloud Shell, aby zwolnić miejsce, możesz usunąć cały katalog domowy. Upewnij się, że wszystko, co chcesz zachować, jest zapisane w innym miejscu.
sudo rm -rf $HOME
Ucz się dalej
- Wdrażanie pełnej aplikacji Next.js w Cloud Run z Cloud SQL dla PostgreSQL przy użyciu łącznika Cloud SQL Node.js
- Wdrażanie pełnej aplikacji Angular w Cloud Run z Cloud SQL for PostgreSQL przy użyciu łącznika Cloud SQL Node.js
- Wdrażanie pełnej aplikacji Angular w Cloud Run z Firestore za pomocą pakietu Node.js Admin SDK
- Wdrażanie aplikacji full stack Next.js w Cloud Run z Firestore za pomocą pakietu Node.js Admin SDK