Com os SDKs de cliente do Firebase SQL Connect, é possível chamar consultas e mutações do lado do servidor diretamente de um app do Firebase. Você gera um SDK de cliente personalizado em paralelo ao projetar os esquemas, as consultas e as mutações que implanta no seu serviço SQL Connect. Em seguida, integre os métodos desse SDK à lógica do cliente.
Como já mencionamos, é importante observar que SQL Connectconsultas e mutações não são enviadas pelo código do cliente e executadas no servidor. Em vez disso, quando implantadas, as operações SQL Connect são armazenadas no servidor, como o Cloud Functions. Isso significa que você precisa implantar as mudanças correspondentes do lado do cliente para evitar falhas nos usuários atuais (por exemplo, em versões mais antigas do app).
Por isso, o SQL Connect oferece um ambiente de desenvolvimento e ferramentas que permitem prototipar seus esquemas, consultas e mutações implantados no servidor. Ele também gera SDKs do lado do cliente automaticamente enquanto você cria protótipos.
Quando você iterar as atualizações nos apps de serviço e cliente, as atualizações do lado do servidor e do cliente estarão prontas para implantação.
Qual é o fluxo de trabalho de desenvolvimento do cliente?
Se você seguiu os Primeiros passos, conheceu o fluxo geral de desenvolvimento para SQL Connect. Neste guia, você encontra informações mais detalhadas sobre como gerar SDKs Swift do seu esquema e trabalhar com consultas e mutações de clientes.
Resumindo, para usar os SDKs Swift gerados nos seus apps cliente, siga estas etapas de pré-requisito:
- Adicione o Firebase ao seu app iOS.
Para usar o SDK gerado, configure-o como uma dependência no Xcode.
Na barra de navegação superior do Xcode, selecione Arquivo > Adicionar dependências de pacote > Adicionar local e escolha a pasta que contém o
Package.swiftgerado.
Depois, siga estas instruções:
- Desenvolva o esquema do app.
Configure a geração de SDKs:
- Com o botão Adicionar SDK ao app na extensão SQL Connect do VS Code
- Atualizando seu
connector.yaml
Configure e use o emulador SQL Connect e faça iterações.
Gerar o SDK do Swift
Use a CLI Firebase para configurar os SDKs gerados por SQL Connect nos seus apps.
O comando init detecta todos os apps na pasta atual e instala os SDKs gerados automaticamente.
firebase init dataconnect:sdk
Atualizar SDKs durante a prototipagem
Se você tiver a extensão do VS Code do SQL Connect instalada, ela sempre vai manter os SDKs gerados atualizados.
Se você não usa a extensão SQL Connect do VS Code, use a CLI do Firebase para manter os SDKs gerados atualizados.
firebase dataconnect:sdk:generate --watchGerar SDKs em pipelines de build
Use a CLI do Firebase para gerar SDKs do SQL Connect em processos de build de CI/CD.
firebase dataconnect:sdk:generateInicializar o SDK do SQL Connect para iOS
Inicialize sua instância SQL Connect usando as informações que você usou para configurar SQL Connect. Encontre essas informações na página Bancos de dados e armazenamento > Conexão SQL do console do Firebase.
Receber uma instância de conector
O código do conector será gerado pelo emulador
SQL Connect. Se o nome do conector for movies e o
pacote for movies, conforme especificado em connector.yaml, recupere o objeto do conector chamando:
let connector = DataConnect.moviesConnector
Implementar consultas e mutações
Com o objeto conector, é possível executar consultas e mutações conforme definido no código-fonte GraphQL. Suponha que seu conector tenha estas operações definidas:
mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
movie_insert(data: {
title: $title
releaseYear: $releaseYear
genre: $genre
rating: $rating
})
}
query getMovieByKey($key: Movie_Key!) {
movie(key: $key) { id title }
}
query listMoviesByGenre($genre: String!) {
movies(where: {genre: {eq: $genre}}) {
id
title
}
}
Em seguida, crie um filme da seguinte maneira:
let mutationResult = try await connector.createMovieMutation.execute(
title: "Empire Strikes Back",
releaseYear: 1980,
genre: "Sci-Fi",
rating: 5)
print("Movie ID: \(mutationResult.data.movie_insert.id)")
Para recuperar um filme, você vai usar uma referência de consulta. Todas as referências de consulta são publishers observáveis. Dependendo do editor configurado (consulte connector.yaml)), eles oferecem suporte à macro @Observable (iOS 17 e versões mais recentes) ou implementam o protocolo ObservableObject. O padrão, se nenhum for especificado, é a macro @Observable compatível com o iOS 17 e versões mais recentes.
Em uma visualização do SwiftUI, é possível vincular os resultados da consulta usando a variável data publicada da referência de consulta e chamar o método execute() da consulta para atualizar os dados. A variável data vai corresponder ao formato dos dados definidos na definição da consulta GQL.
Todos os resultados recuperados estão em conformidade com o protocolo Decodable. Se você incluiu a chave primária do objeto na busca de GQL, os objetos também são Identifiable, permitindo que você os use em iteradores.
struct ListMovieView: View {
@StateObject private var queryRef = connector.listMoviesByGenreQuery.ref(genre: "Sci-Fi")
var body: some View {
VStack {
Button {
Task {
do {
try await refresh()
} catch {
print("Failed to refresh: \(error)")
}
}
} label: {
Text("Refresh")
}
// use the query results in a view
ForEach(queryRef.data?.movies ?? [], id: \.self.id) { movie in
Text(movie.title)
}
}
}
@MainActor
func refresh() async throws {
_ = try await queryRef.execute()
}
}
As consultas também são compatíveis com a execução única.
let resultData = try await DataConnect.moviesConnector.listMoviesByGenreQuery.execute(genre: "Sci-Fi")
Inscrever-se para receber notificações sobre mudanças
Consulte Receber atualizações em tempo real de SQL Connect.
Processar mudanças nos campos de enumeração
O esquema de um app pode conter enumerações, que podem ser acessadas pelas suas consultas do GraphQL.
À medida que o design de um app muda, você pode adicionar novos valores compatíveis com enumeração. Por exemplo, imagine que, mais tarde no ciclo de vida do aplicativo, você decida adicionar um valor
FULLSCREEN à enumeração AspectRatio.
No fluxo de trabalho do SQL Connect, você pode usar ferramentas de desenvolvimento local para atualizar suas consultas e SDKs.
No entanto, antes de lançar uma versão atualizada dos clientes, os clientes implantados mais antigos podem falhar.
Exemplo de implementação resiliente
O SDK gerado força o processamento de valores desconhecidos, já que as enumerações geradas
contêm um valor _UNKNOWN, e o Swift exige instruções de switch exaustivas.
do {
let result = try await DataConnect.moviesConnector.listMovies.execute()
if let data = result.data {
for movie in data.movies {
switch movie.aspectratio {
case .ACADEMY: print("academy")
case .WIDESCREEN: print("widescreen")
case .ANAMORPHIC: print("anamorphic")
case ._UNKNOWN(let unknownAspect): print(unknownAspect)
}
}
}
} catch {
// handle error
}
Ativar o armazenamento em cache do lado do cliente
O SQL Connect tem um recurso opcional de cache do lado do cliente, que você
pode ativar editando o arquivo connector.yaml. Quando esse recurso está ativado, os SDKs de cliente gerados armazenam em cache localmente as respostas de consulta, o que pode reduzir o número de solicitações de banco de dados feitas pelo app e permitir que as partes dependentes do banco de dados funcionem quando a disponibilidade da rede é interrompida.
Para ativar o armazenamento em cache do lado do cliente, adicione uma configuração de cache do cliente à configuração do conector:
generate:
swiftSdk:
outputDir: "../ios"
package: "FirebaseDataConnectGenerated"
clientCache:
maxAge: 5s
storage: persistent
Essa configuração tem dois parâmetros, ambos opcionais:
maxAge: a idade máxima que uma resposta em cache pode ter antes que o SDK do cliente busque valores atualizados. Exemplos: "0", "30s", "1h30m".O valor padrão de
maxAgeé0, o que significa que as respostas são armazenadas em cache, mas o SDK do cliente sempre busca valores atualizados. Os valores armazenados em cache só serão usados quandoCACHE_ONLYfor especificado comoexecute().storage: o SDK do cliente pode ser configurado para armazenar em cache respostas no armazenamentopersistentou emmemory. Os resultados armazenados em cache no armazenamentopersistentserão mantidos entre as reinicializações do app. Nos SDKs do iOS, o padrão épersistent.
Depois de atualizar a configuração de cache do conector, gere novamente os SDKs
do cliente e reconstrua o app. Depois disso, o execute()
vai armazenar em cache
respostas e usar valores armazenados em cache de acordo com a política configurada. Isso geralmente acontece de forma automática, sem que você precise seguir etapas adicionais. No entanto, observe o seguinte:
O comportamento padrão de
execute()é o descrito acima: se um resultado for armazenado em cache para uma consulta e o valor armazenado em cache não for mais antigo quemaxAge, use o valor armazenado em cache. Esse comportamento padrão é chamado de política dePREFER_CACHE.Também é possível especificar invocações individuais de
execute()para disponibilizar apenas valores em cache (CACHE_ONLY) ou buscar incondicionalmente valores atualizados do servidor (SERVER_ONLY).try await execute(fetchPolicy: .cacheOnly)try await execute(fetchPolicy: .serverOnly)Criar protótipos e testar seu aplicativo iOS
Você pode usar o emulador local para testar e criar protótipos do aplicativo.
Instrumentar clientes para usar um emulador local
É possível usar o emulador SQL Connect, seja da extensão SQL Connect do VS Code ou da CLI.
A instrumentação do app para se conectar ao emulador é a mesma nos dois cenários.
let connector = DataConnect.moviesConnector // Connect to the emulator on "127.0.0.1:9399" connector.useEmulator() // (alternatively) if you're running your emulator on non-default port: connector.useEmulator(port: 9999) // Make calls from your appTipos de dados nos SDKs SQL Connect
O servidor SQL Connect representa tipos de dados GraphQL comuns e personalizados. Elas são representadas no SDK da seguinte maneira.
Tipo SQL Connect Swift String String Int Int Ponto flutuante Duplo Booleano Booleano UUID UUID Data FirebaseDataConnect.LocalDate Carimbo de data/hora FirebaseCore.Timestamp Int64 Int64 Qualquer FirebaseDataConnect.AnyValue