From 05dca02b78d2b304b3ea7ccf2c74025bd84611ce Mon Sep 17 00:00:00 2001 From: Alisson Nunes Date: Sat, 8 Aug 2026 08:53:05 -0300 Subject: [PATCH 1/2] Create firebase --- .../docs/pt-br/guides/backend/firebase.mdx | 932 ++++++++++++++++++ 1 file changed, 932 insertions(+) create mode 100644 src/content/docs/pt-br/guides/backend/firebase.mdx diff --git a/src/content/docs/pt-br/guides/backend/firebase.mdx b/src/content/docs/pt-br/guides/backend/firebase.mdx new file mode 100644 index 0000000000000..434354c6d0f97 --- /dev/null +++ b/src/content/docs/pt-br/guides/backend/firebase.mdx @@ -0,0 +1,932 @@ +--- +title: Firebase & Astro +description: Adicione um backend ao seu projeto com o Firebase +sidebar: + label: Firebase +type: backend +logo: firebase +stub: false +i18nReady: true +--- +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro' +import { FileTree } from '@astrojs/starlight/components'; + + +[Firebase](https://firebase.google.com/) é uma plataforma de desenvolvimento de aplicativos que fornece banco de dados NoSQL, autenticação, inscrições em tempo real, funções e armazenamento. + +Veja nosso guia separado para [implantar na hospedagem do Firebase](/pt-br/guides/deploy/firebase/). + +## Inicializando o Firebase no Astro + +### Pré-requisitos + +- Um [projeto Firebase com um aplicativo web configurado](https://firebase.google.com/docs/web/setup). +- Um projeto Astro com [`output: 'server'` para renderização sob demanda](/pt-br/guides/on-demand-rendering/) ativado. +- Credenciais do Firebase: Você precisará de dois conjuntos de credenciais para conectar o Astro ao Firebase: + - Credenciais de aplicativo web: Essas credenciais serão usadas pelo lado do cliente do seu aplicativo. Você pode encontrá-las no console do Firebase em *Configurações do projeto > Geral*. Role para baixo até a seção **Seus aplicativos** e clique no ícone **Aplicativo Web**. + - Credenciais do projeto: Essas credenciais serão usadas pelo lado do servidor do seu aplicativo. Você pode gerá-las no console do Firebase em *Configurações do projeto > Contas de serviço > SDK Admin do Firebase > Gerar nova chave privada*. + +### Adicionando credenciais do Firebase + +Para adicionar suas credenciais do Firebase ao Astro, crie um arquivo `.env` na raiz do seu projeto com as seguintes variáveis: + +```ini title=".env" +FIREBASE_PRIVATE_KEY_ID=SUA_CHAVE_PRIVADA_ID +FIREBASE_PRIVATE_KEY=SUA_CHAVE_PRIVADA +FIREBASE_PROJECT_ID=SEU_PROJECT_ID +FIREBASE_CLIENT_EMAIL=SEU_CLIENT_EMAIL +FIREBASE_CLIENT_ID=SEU_CLIENT_ID +FIREBASE_AUTH_URI=SEU_AUTH_URI +FIREBASE_TOKEN_URI=SEU_TOKEN_URI +FIREBASE_AUTH_CERT_URL=SEU_AUTH_CERT_URL +FIREBASE_CLIENT_CERT_URL=SEU_CLIENT_CERT_URL +``` + +Agora, essas variáveis de ambiente estão disponíveis para uso no seu projeto. + +Se você gostaria de ter IntelliSense para suas variáveis de ambiente do Firebase, edite ou crie o arquivo `env.d.ts` no seu diretório `src/` e configure seus tipos: + +```ts title="src/env.d.ts" +interface ImportMetaEnv { + readonly FIREBASE_PRIVATE_KEY_ID: string; + readonly FIREBASE_PRIVATE_KEY: string; + readonly FIREBASE_PROJECT_ID: string; + readonly FIREBASE_CLIENT_EMAIL: string; + readonly FIREBASE_CLIENT_ID: string; + readonly FIREBASE_AUTH_URI: string; + readonly FIREBASE_TOKEN_URI: string; + readonly FIREBASE_AUTH_CERT_URL: string + readonly FIREBASE_CLIENT_CERT_URL: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} +``` + +:::tip +Leia mais sobre [variáveis de ambiente](/pt-br/guides/environment-variables/) e arquivos `.env` no Astro. +::: + +Seu projeto agora deve incluir estes novos arquivos: + + +- src/ + - **env.d.ts** +- **.env** +- astro.config.mjs +- package.json + + + +### Instalando dependências + +Para conectar o Astro ao Firebase, instale os seguintes pacotes usando o único comando abaixo no seu gerenciador de pacotes preferido: + +- `firebase` - o SDK do Firebase para o lado do cliente +- `firebase-admin` - o SDK Admin do Firebase para o lado do servidor + + + + ```shell + npm install firebase firebase-admin + ``` + + + ```shell + pnpm add firebase firebase-admin + ``` + + + ```shell + yarn add firebase firebase-admin + ``` + + + +Em seguida, crie uma pasta chamada `firebase` no diretório `src/` e adicione dois novos arquivos a essa pasta: `client.ts` e `server.ts`. + +Em `client.ts`, adicione o seguinte código para inicializar o Firebase no cliente usando as credenciais do seu aplicativo web e o pacote `firebase`: + +```ts title="src/firebase/client.ts" +import { initializeApp } from "firebase/app"; + +const firebaseConfig = { + apiKey: "minha-chave-api-publica", + authDomain: "meu-dominio-autenticacao", + projectId: "meu-id-projeto", + storageBucket: "meu-bucket-armazenamento", + messagingSenderId: "meu-id-remetente", + appId: "meu-id-aplicacao", +}; + +export const app = initializeApp(firebaseConfig); +``` + +:::note +Lembre-se de substituir o objeto `firebaseConfig` com suas próprias credenciais de aplicativo web. +::: + +Em `server.ts`, adicione o seguinte código para inicializar o Firebase no servidor usando as credenciais do seu projeto e o pacote `firebase-admin`: + +```ts title="src/firebase/server.ts" +import type { ServiceAccount } from "firebase-admin"; +import { initializeApp, cert, getApps } from "firebase-admin/app"; + +const activeApps = getApps(); +const serviceAccount = { + type: "service_account", + project_id: import.meta.env.FIREBASE_PROJECT_ID, + private_key_id: import.meta.env.FIREBASE_PRIVATE_KEY_ID, + private_key: import.meta.env.FIREBASE_PRIVATE_KEY, + client_email: import.meta.env.FIREBASE_CLIENT_EMAIL, + client_id: import.meta.env.FIREBASE_CLIENT_ID, + auth_uri: import.meta.env.FIREBASE_AUTH_URI, + token_uri: import.meta.env.FIREBASE_TOKEN_URI, + auth_provider_x509_cert_url: import.meta.env.FIREBASE_AUTH_CERT_URL, + client_x509_cert_url: import.meta.env.FIREBASE_CLIENT_CERT_URL, +}; + +const initApp = () => { + if (import.meta.env.PROD) { + console.info('Ambiente de produção detectado. Usando a conta de serviço padrão.') + // Usar configuração padrão nas funções do firebase. Já deve estar injetada no servidor pelo Firebase. + return initializeApp() + } + console.info('Carregando a conta de serviço das variáveis de ambiente.') + return initializeApp({ + credential: cert(serviceAccount as ServiceAccount) + }) +} + +export const app = activeApps.length === 0 ? initApp() : activeApps[0]; +``` + +:::note +Lembre-se de substituir o objeto `serviceAccount` com suas próprias credenciais do projeto. +::: + +Por fim, seu projeto agora deve incluir estes novos arquivos: + + +- src + - env.d.ts + - firebase + - **client.ts** + - **server.ts** +- .env +- astro.config.mjs +- package.json + + +## Adicionando autenticação com o Firebase + +### Pré-requisitos + +- Um projeto Astro [inicializado com o Firebase](#inicializando-o-firebase-no-astro). +- Um projeto Firebase com autenticação de e-mail/senha ativada no console do Firebase sob o método *Authentication > Sign-in*. + +### Criando endpoints de servidor para auth + +A autenticação do Firebase no Astro exige os três seguintes [endpoints de servidor do Astro](/pt-br/guides/endpoints/): + +- `GET /api/auth/entrar` - para entrar com um usuário +- `GET /api/auth/sair` - para desconectar um usuário +- `POST /api/auth/registrar` - para registrar um usuário + +Crie três endpoints relacionados à autenticação em um novo diretório `src/pages/api/auth/`: `entrar.ts`, `sair.ts` e `registrar.ts`. + +`entrar.ts` contém o código para autenticar um usuário usando o Firebase: + +```ts title="src/pages/api/auth/entrar.ts" +import type { APIRoute } from "astro"; +import { app } from "../../../firebase/server"; +import { getAuth } from "firebase-admin/auth"; + +export const GET: APIRoute = async ({ request, cookies, redirect }) => { + const auth = getAuth(app); + + /* Obter token dos cabeçalhos da requisição */ + const tokenId = request.headers.get("Authorization")?.split("Bearer ")[1]; + if (!tokenId) { + return new Response( + "Token não encontrado", + { status: 401 } + ); + } + + /* Verificar token de id */ + try { + await auth.verifyIdToken(tokenId); + } catch (erro) { + return new Response( + "Token inválido", + { status: 401 } + ); + } + + /* Criar e definir cookie de sessão */ + const fiveDays = 60 * 60 * 24 * 5 * 1000; + const cookieSessao = await auth.createSessionCookie(tokenId, { + expiresIn: fiveDays, + }); + + cookies.set("__session", cookieSessao, { + path: "/", + }); + + return redirect("/dashboard"); +}; +``` + +:::caution +O Firebase permite apenas o uso de [um cookie, e ele deve se chamar `__session`](https://firebase.google.com/docs/hosting/manage-cache#using_cookies). Quaisquer outros cookies enviados pelo cliente não serão visíveis para sua aplicação. +::: + +:::note +Esta é uma implementação básica do endpoint de entrada. Você pode adicionar mais lógica a este endpoint para atender às suas necessidades. +::: + +`sair.ts` contém o código para desconectar um usuário excluindo o cookie de sessão: + +```ts title="src/pages/api/auth/sair.ts" +import type { APIRoute } from "astro"; + +export const GET: APIRoute = async ({ redirect, cookies }) => { + cookies.delete("__session", { + path: "/", + }); + return redirect("/entrar"); +}; +``` + +:::note +Esta é uma implementação básica do endpoint de saída. Você pode adicionar mais lógica a este endpoint para atender às suas necessidades. +::: + +`registrar.ts` contém o código para registrar um usuário usando o Firebase: + +```ts title="src/pages/api/auth/registrar.ts" +import type { APIRoute } from "astro"; +import { getAuth } from "firebase-admin/auth"; +import { app } from "../../../firebase/server"; + +export const POST: APIRoute = async ({ request, redirect }) => { + const auth = getAuth(app); + + /* Obter dados do formulário */ + const dadosFormulario = await request.formData(); + const email = dadosFormulario.get("email")?.toString(); + const senha = dadosFormulario.get("senha")?.toString(); + const nome = dadosFormulario.get("nome")?.toString(); + + if (!email || !senha || !nome) { + return new Response( + "Dados do formulário ausentes", + { status: 400 } + ); + } + + /* Criar usuário */ + try { + await auth.createUser({ + email, + password: senha, + displayName: nome, + }); + } catch (error: any) { + return new Response( + "Ocorreu um erro ao criar o usuário", + { status: 400 } + ); + } + return redirect("/entrar"); +}; +``` + +:::note +Esta é uma implementação básica do endpoint de registro. Você pode adicionar mais lógica a este endpoint para atender às suas necessidades. +::: + +Após criar os endpoints de servidor para autenticação, o diretório do seu projeto agora deve incluir estes novos arquivos: + + +- src + - env.d.ts + - firebase + - client.ts + - server.ts + - pages + - api + - auth + - **entrar.ts** + - **sair.ts** + - **registrar.ts** +- .env +- astro.config.mjs +- package.json + + +### Criando páginas + +Crie as páginas que usarão os endpoints do Firebase: + +- `src/pages/registrar` - conterá um formulário para registrar um usuário +- `src/pages/entrar` - conterá um formulário para autenticar um usuário +- `src/pages/dashboard` - conterá um painel que só pode ser acessado por usuários autenticados + +O exemplo `src/pages/registrar.astro` abaixo inclui um formulário que enviará uma requisição `POST` para o endpoint `/api/auth/registrar`. Este endpoint criará um novo usuário usando os dados do formulário e então redirecionará o usuário para a página `/entrar`. + +```astro title="src/pages/registrar.astro" +--- +import Layout from "../layouts/Layout.astro"; +--- + + +

Registrar

+

Já possui uma conta? Entrar

+
+ + + + + + + +
+
+``` + +`src/pages/entrar.astro` usa o app do Firebase Server para verificar o cookie de sessão do usuário. Se o usuário estiver autenticado, a página redirecionará o usuário para a página `/dashboard`. + +A página de exemplo abaixo contém um formulário que enviará uma requisição `POST` para o endpoint `/api/auth/entrar` com o token de ID gerado pelo aplicativo cliente do Firebase. + +O endpoint verificará o token de ID e criará um novo cookie de sessão para o usuário. Em seguida, o endpoint redirecionará o usuário para a página `/dashboard`. + +```astro title="src/pages/entrar.astro" +--- +import { app } from "../firebase/server"; +import { getAuth } from "firebase-admin/auth"; +import Layout from "../layouts/Layout.astro"; + +/* Verificar se o usuário está autenticado */ +const auth = getAuth(app); +if (Astro.cookies.has("__session")) { + const cookieSessao = Astro.cookies.get("__session")!.value; + const cookieDecodificado = await auth.verifySessionCookie(cookieSessao); + if (cookieDecodificado) { + return Astro.redirect("/dashboard"); + } +} +--- + + +

Entrar

+

Novo por aqui? Criar uma conta

+
+ + + + + +
+
+ +``` + +`src/pages/dashboard.astro` verificará o cookie de sessão do usuário usando o aplicativo de servidor do Firebase. Se o usuário não estiver autenticado, a página redirecionará o usuário para a página `/entrar`. + +A página de exemplo abaixo exibe o nome do usuário e um botão para sair. Clicar no botão enviará uma requisição `GET` para o endpoint `/api/auth/sair`. + +O endpoint excluirá o cookie de sessão do usuário e redirecionará o usuário para a página `/entrar`. + +```astro title="src/pages/dashboard.astro" +--- +import { app } from "../firebase/server"; +import { getAuth } from "firebase-admin/auth"; +import Layout from "../layouts/Layout.astro"; + +const auth = getAuth(app); + +/* Verificar sessão atual */ +if (!Astro.cookies.has("__session")) { + return Astro.redirect("/entrar"); +} +const cookieSessao = Astro.cookies.get("__session")!.value; +const cookieDecodificado = await auth.verifySessionCookie(cookieSessao); +const usuario = await auth.getUser(cookieDecodificado.uid); + +if (!usuario) { + return Astro.redirect("/entrar"); +} +--- + + +

Bem-vindo(a) {usuario.displayName}

+

Ficamos felizes em ver você aqui

+
+ +
+
+``` + +### Adicionando provedores OAuth + +Para adicionar provedores OAuth ao seu aplicativo, você precisa ativá-los no console do Firebase. + +No console do Firebase, vá para a seção **Authentication** e clique na aba **Método de login**. Em seguida, clique no botão **Adicionar novo fornecedor** e ative os provedores que deseja usar. + +O exemplo abaixo usa o provedor do **Google**. + +Edite a página `entrar.astro` para adicionar: +- um botão para entrar com o Google abaixo do formulário existente +- um ouvinte de evento no botão para manipular o processo de login no ` +``` + +Quando clicado, o botão de entrar com o Google abrirá uma janela pop-up para fazer login com o Google. Assim que o usuário entrar, ele enviará uma requisição `POST` para o endpoint `/api/auth/entrar` com o token de ID gerado pelo provedor OAuth. + +O endpoint verificará o token de ID e criará um novo cookie de sessão para o usuário. Em seguida, o endpoint redirecionará o usuário para a página `/dashboard`. + +## Conectando ao banco de dados Firestore + +### Pré-requisitos + +- Um projeto Astro inicializado com o Firebase conforme descrito na seção [Inicializando o Firebase no Astro](#inicializando-o-firebase-no-astro). + +- Um projeto Firebase com um banco de dados Firestore. Você pode seguir a [documentação do Firebase para criar um novo projeto e configurar um banco de dados Firestore](https://firebase.google.com/docs/firestore/quickstart?hl=pt-br). + +Nesta receita, a coleção do Firestore será chamada de **amigos** e conterá documentos com os seguintes campos: + +- `id`: gerado automaticamente pelo Firestore +- `nome`: um campo do tipo string +- `idade`: um campo do tipo number +- `eMelhorAmigo`: um campo do tipo boolean + +### Criando os endpoints do servidor + +Crie dois novos arquivos em um novo diretório `src/pages/api/amigos/`: `index.ts` e `[id].ts`. Eles criarão dois endpoints de servidor para interagir com o banco de dados Firestore das seguintes maneiras: + +- `POST /api/amigos`: para criar um novo documento na coleção de amigos. +- `POST /api/amigos/:id`: para atualizar um documento na coleção de amigos. +- `DELETE /api/amigos/:id`: para excluir um documento na coleção de amigos. + +`index.ts` conterá o código para criar um novo documento na coleção de amigos: + +```ts title="src/pages/api/amigos/index.ts" +import type { APIRoute } from "astro"; +import { app } from "../../../firebase/server"; +import { getFirestore } from "firebase-admin/firestore"; + +export const POST: APIRoute = async ({ request, redirect }) => { + const dadosFormulario = await request.formData(); + const nome = dadosFormulario.get("nome")?.toString(); + const idade = dadosFormulario.get("idade")?.toString(); + const eMelhorAmigo = dadosFormulario.get("eMelhorAmigo") === "on"; + + if (!nome || !idade) { + return new Response("Campos obrigatórios ausentes", { + status: 400, + }); + } + try { + const bd = getFirestore(app); + const refAmigos = bd.collection("amigos"); + await refAmigos.add({ + nome, + idade: parseInt(idade), + eMelhorAmigo, + }); + } catch (erro) { + return new Response("Ocorreu um erro", { + status: 500, + }); + } + return redirect("/dashboard"); +}; +``` + +:::note +Esta é uma implementação básica do endpoint `amigos`. Você pode adicionar mais lógica a este endpoint para atender às suas necessidades. +::: + +`[id].ts` conterá o código para atualizar e excluir um documento na coleção de amigos: + +```ts title="src/pages/api/amigos/[id].ts" +import type { APIRoute } from "astro"; +import { app } from "../../../firebase/server"; +import { getFirestore } from "firebase-admin/firestore"; + +const bd = getFirestore(app); +const refAmigos = bd.collection("amigos"); + +export const POST: APIRoute = async ({ params, redirect, request }) => { + const dadosFormulario = await request.formData(); + const nome = dadosFormulario.get("nome")?.toString(); + const idade = dadosFormulario.get("idade")?.toString(); + const eMelhorAmigo = dadosFormulario.get("eMelhorAmigo") === "on"; + + if (!nome || !idade) { + return new Response("Campos obrigatórios ausentes", { + status: 400, + }); + } + + if (!params.id) { + return new Response("Amigo não encontrado", { + status: 404, + }); + } + + try { + await refAmigos.doc(params.id).update({ + nome, + idade: parseInt(idade), + eMelhorAmigo, + }); + } catch (erro) { + return new Response("Ocorreu um erro", { + status: 500, + }); + } + return redirect("/dashboard"); +}; + +export const DELETE: APIRoute = async ({ params, redirect }) => { + if (!params.id) { + return new Response("Amigo não encontrado", { + status: 404, + }); + } + + try { + await refAmigos.doc(params.id).delete(); + } catch (erro) { + return new Response("Ocorreu um erro", { + status: 500, + }); + } + return redirect("/dashboard"); +}; +``` + +:::note +Esta é uma implementação básica do endpoint `amigos/:id`. Você pode adicionar mais lógica a este endpoint para atender às suas necessidades. +::: + +Após criar os endpoints de servidor para o Firestore, o diretório do seu projeto agora deve incluir estes novos arquivos: + + +- src + - env.d.ts + - firebase + - client.ts + - server.ts + - pages + - api + - amigos + - **index.ts** + - **[id].ts** +- .env +- astro.config.mjs +- package.json + + +### Criando páginas + +Crie as páginas que usarão os endpoints do Firestore: + +- `src/pages/adicionar.astro` - conterá um formulário para adicionar um novo amigo. +- `src/pages/editar/[id].astro` - conterá um formulário para editar um amigo e um botão para excluir um amigo. +- `src/pages/amigo/[id].astro` - conterá os detalhes de um amigo. +- `src/pages/dashboard.astro` - exibirá uma lista de amigos. + +#### Adicionar um novo registro + +O exemplo `src/pages/adicionar.astro` abaixo inclui um formulário que enviará uma requisição `POST` para o endpoint `/api/amigos`. Este endpoint criará um novo amigo usando os dados do formulário e então redirecionará o usuário para a página `/dashboard`. + +```astro title="src/pages/adicionar.astro" +--- +import Layout from "../layouts/Layout.astro"; +--- + + +

Adicionar um novo amigo

+
+ + + + + + + +
+
+``` + +#### Editar ou Excluir um registro + +`src/pages/editar/[id].astro` conterá um formulário para editar os dados de um amigo e um botão para excluir um amigo. Ao enviar, esta página enviará uma requisição `POST` para o endpoint `/api/amigos/:id` para atualizar os dados de um amigo. + +Se o usuário clicar no botão de excluir, esta página enviará uma requisição `DELETE` para o endpoint `/api/amigos/:id` para excluir o amigo. + +```astro title="src/pages/editar/[id].astro" +--- +import Layout from "../../layouts/Layout.astro"; +import { app } from "../../firebase/server"; +import { getFirestore } from "firebase-admin/firestore"; + +interface Amigo { + name: string; + idade: number; + eMelhorAmigo: boolean; +} + +const { id } = Astro.params; + +if (!id) { + return Astro.redirect("/404"); +} + +const bd = getFirestore(app); +const refAmigos = bd.collection("amigos"); +const snapshotAmigo = await refAmigos.doc(id).get(); + +if (!snapshotAmigo.exists) { + return Astro.redirect("/404"); +} + +const amigo = snapshotAmigo.data() as Amigo; +--- + + +

Editar {amigo.nome}

+

Aqui você pode editar ou excluir os dados do seu amigo.

+
+ + + + + + + +
+ +
+ +``` + +#### Exibir um registro individual + +`src/pages/amigo/[id].astro` exibirá os detalhes de um amigo. + +```astro title="src/pages/amigo/[id].astro" +--- +import Layout from "../../layouts/Layout.astro"; +import { app } from "../../firebase/server"; +import { getFirestore } from "firebase-admin/firestore"; + +interface Amigo { + nome: string; + idade: number; + eMelhorAmigo: boolean; +} + +const { id } = Astro.params; + +if (!id) { + return Astro.redirect("/404"); +} + +const bd = getFirestore(app); +const refAmigos = bd.collection("amigos"); +const snapshotAmigo = await refAmigos.doc(id).get(); + +if (!snapshotAmigo.exists) { + return Astro.redirect("/404"); +} + +const amigo = snapshotAmigo.data() as Amigo; +--- + + +

{amigo.nome}

+

Idade: {amigo.idade}

+

É melhor amigo: {amigo.eMelhorAmigo ? "Sim" : "Não"}

+
+``` + +#### Exibir uma lista de registros com um botão de edição + +Por fim, `src/pages/dashboard.astro` exibirá uma lista de amigos. Cada amigo terá um link para a página de detalhes e um botão de edição que redirecionará o usuário para a página de edição. + +```astro title="src/pages/dashboard.astro" +--- +import { app } from "../firebase/server"; +import { getFirestore } from "firebase-admin/firestore"; +import Layout from "../layouts/Layout.astro"; + +interface Amigo { + id: string; + nome: string; + idade: number; + eMelhorAmigo: boolean; +} + +const bd = getFirestore(app); +const refAmigos = bd.collection("amigos"); +const amigosSnapshot = await refAmigos.get(); +const amigos = amigosSnapshot.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), +})) as Amigo[]; +--- + + +

Amigos

+ +
+ +``` + +Após criar todas as páginas, você deve ter a seguinte estrutura de arquivos: + + +- src + - env.d.ts + - firebase + - client.ts + - server.ts + - pages + - dashboard.astro + - adicionar.astro + - editar + - [id].astro + - amigo + - [id].astro + - api + - amigos + - index.ts + - [id].ts +- .env +- astro.config.mjs +- package.json + + +## Recursos da Comunidade + +- [Exemplo de app SSR com Astro e Firebase](https://github.com/kevinzunigacuellar/astro-firebase) +- [Usando Firebase Realtime Database no Astro com Vue: Um Guia Passo a Passo](https://www.launchfa.st/blog/vue-astro-firebase-realtime-database) From 9c21aee6ba7e0d63e36ab7819d893ff48e39bbd5 Mon Sep 17 00:00:00 2001 From: Alisson Nunes Date: Sat, 8 Aug 2026 09:10:45 -0300 Subject: [PATCH 2/2] Create prisma postgres --- .../pt-br/guides/backend/prisma-postgres.mdx | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 src/content/docs/pt-br/guides/backend/prisma-postgres.mdx diff --git a/src/content/docs/pt-br/guides/backend/prisma-postgres.mdx b/src/content/docs/pt-br/guides/backend/prisma-postgres.mdx new file mode 100644 index 0000000000000..8ca3d91d0c2c3 --- /dev/null +++ b/src/content/docs/pt-br/guides/backend/prisma-postgres.mdx @@ -0,0 +1,191 @@ +--- +title: Prisma Postgres & Astro +description: Adicione um banco de dados Postgres serverless ao seu projeto Astro com o Prisma Postgres +sidebar: + label: Prisma Postgres +type: backend +logo: 'prisma-postgres' +stub: false +i18nReady: true +--- + +import ReadMore from '~/components/ReadMore.astro'; + +[Prisma Postgres](https://www.prisma.io/) é um banco de dados Postgres totalmente gerenciado e serverless construído para aplicativos web modernos. + +## Conectar com o Prisma ORM (Recomendado) + +O [Prisma ORM](https://www.prisma.io/orm) é a forma recomendada de se conectar ao seu banco de dados Prisma Postgres. Ele oferece consultas com segurança de tipos (type-safe), migrações e desempenho global. + +### Pré-requisitos +- Um projeto Astro com um adaptador instalado para ativar a [renderização sob demanda (SSR)](/pt-br/guides/on-demand-rendering/). + +### Instalar dependências e inicializar o Prisma + +Execute os seguintes comandos para instalar as dependências necessárias do Prisma: + +```bash +npm install prisma tsx --save-dev +npm install @prisma/adapter-pg @prisma/client +``` + +Uma vez instalado, inicialize o Prisma no seu projeto com o seguinte comando: + +```bash +npx prisma init --db --output ./generated +``` + +Você precisará responder a algumas perguntas ao configurar seu banco de dados Prisma Postgres. Selecione a região mais próxima da sua localização e um nome memorável para o seu banco de dados, como "Meu Projeto Astro". + +Isso criará: +- Um diretório `prisma/` com um arquivo `schema.prisma` +- Um arquivo `.env` com a variável `DATABASE_URL` já configurada + +### Definir um Modelo + +Mesmo se você não precisar de modelos de dados específicos ainda, o Prisma requer pelo menos um modelo no schema para gerar um cliente e aplicar migrações. + +O exemplo a seguir define um modelo `Postagem` como modelo provisório. Adicione o modelo ao seu schema para começar. Você pode excluí-lo ou substituí-lo com segurança mais tarde por modelos que reflitam seus dados reais. + +```prisma title="prisma/schema.prisma" ins={11-16} +generator client { + provider = "prisma-client" + output = "./generated" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Postagem { + id Int @id @default(autoincrement()) + titulo String + conteudo String? + publicada Boolean @default(false) +} +``` + +Saiba mais sobre como configurar a sua instalação do Prisma ORM na [referência do schema do Prisma](https://www.prisma.io/docs/concepts/components/prisma-schema). + +### Gerar cliente + +Execute o seguinte comando para gerar o Prisma Client a partir do seu schema: + +```bash +npx prisma generate +``` + +### Gerar arquivos de migração + +Execute o seguinte comando para criar as tabelas do banco de dados e gerar o Prisma Client a partir do seu schema. Isso também criará um diretório `prisma/migrations/` com arquivos do histórico de migrações. + +```bash +npx prisma migrate dev --name init +``` + +### Criar um Prisma Client + +Dentro de `/src/lib`, crie um arquivo `prisma.ts`. Este arquivo inicializará e exportará a instância do seu Prisma Client para que você possa consultar seu banco de dados em todo o seu projeto Astro. + +```typescript title="src/lib/prisma.ts" +import { PrismaPg } from '@prisma/adapter-pg'; +import { PrismaClient } from '../../prisma/generated/client'; + +const stringConexao = import.meta.env.DATABASE_URL; +const adaptador = new PrismaPg({ connectionString: stringConexao }); +const prisma = new PrismaClient({ adapter: adaptador }); + +export default prisma; +``` + +### Consultando e exibindo dados + +O exemplo a seguir mostra a busca apenas das suas postagens publicadas com o Prisma Client ordenadas por `id`, e então exibindo os títulos e o conteúdo da postagem no seu modelo do Astro: + +```astro title="src/pages/postagens.astro" {2, 4-7} +--- +import prisma from '../lib/prisma'; + +const postagens = await prisma.post.findMany({ + where: { publicado: true }, + orderBy: { id: 'desc' } +}); +--- + + + + Postagens Publicadas + + +

Postagens Publicadas

+ + + +``` + +A melhor prática é lidar com consultas em uma rota de API. Para mais informações sobre como usar o Prisma ORM no seu projeto Astro, veja o [Guia Astro + Prisma ORM](https://www.prisma.io/docs/guides/frameworks/astro). + +## Conectar com Outros ORMs e Bibliotecas + +Você pode se conectar ao Prisma Postgres via TCP direto usando qualquer outro ORM, biblioteca de banco de dados ou ferramenta de sua escolha. Crie uma string de conexão direta no seu Console Prisma para começar. + +### Pré-requisitos +- Um projeto Astro com um adaptador instalado para ativar a [renderização sob demanda (SSR)](/pt-br/guides/on-demand-rendering/). +- Um banco de dados [Prisma Postgres](https://pris.ly/ppg) com uma string de conexão com TCP ativado + +### Instalar dependências + +Este exemplo usa [`pg`, um cliente PostgreSQL para Node.js](https://github.com/brianc/node-postgres) para fazer uma conexão TCP direta. + +Execute o seguinte comando para instalar o pacote `pg`: + +```bash +npm install pg +``` + +### Consultar o cliente do seu banco de dados + +Forneça sua string de conexão para o cliente `pg` para se comunicar com o seu servidor SQL e buscar dados do seu banco de dados. + +O exemplo a seguir de criação de uma tabela e inserção de dados pode ser usado para validar sua URL de consulta e conexão TCP: + +```astro title="src/pages/index.astro" {2-19} +--- +import { Client } from 'pg'; +const client = new Client({ + connectionString: import.meta.env.DATABASE_URL, + ssl: { rejectUnauthorized: false } +}); +await client.connect(); + +await client.query(` + CREATE TABLE IF NOT EXISTS postagens ( + id SERIAL PRIMARY KEY, + titulo TEXT UNIQUE, + conteudo TEXT + ); + + INSERT INTO postagens (titulo, conteudo) + VALUES ('Olá', 'Mundo') + ON CONFLICT (titulo) DO NOTHING; +`); + +const { rows } = await client.query('SELECT * FROM postagens'); +await client.end(); +--- + +

Postagens

+

{rows[0].titulo}: {rows[0].conteudo}

+``` + +## Recursos Oficiais + +- [Guia Astro + Prisma ORM](https://www.prisma.io/docs/guides/frameworks/astro)