快速入门: Android Kotlin
第一步:在 MemFire Cloud 仪表板中创建一个新应用。#
应用准备就绪后,进入应用,在左侧菜单->表编辑器选择 SQL 编辑器在 MemFire Cloud 数据库中创建一个表。使用以下 SQL 语句创建包含一些示例数据的国家/地区表。
-- Create the table CREATE TABLE countries ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL ); -- Insert some sample data into the table INSERT INTO countries (name) VALUES ('United States'); INSERT INTO countries (name) VALUES ('Canada'); INSERT INTO countries (name) VALUES ('Mexico');
第二步:使用 Android Studio 创建 Android 应用#
打开 Android Studio > 新建 > 新建 Android 项目。
npm create vite@latest my-app -- --template react
第三步:安装 Supabase 客户端库#
导入 Supabase 和所有必需的依赖项。将版本占位符 $supabase_version 和 $ktor_version 替换为各自的最新版本。
implementation "io.github.jan-tennert.supabase:postgrest-kt:$supabase_version" implementation "io.ktor:ktor-client-android:$ktor_version"
第四步: 安装序列化插件#
打开build.gradle(app),添加序列化插件以使用注解进行数据解析。请注意,插件版本应与应用中的 Kotlin 版本相同。
plugins { ... id 'org.jetbrains.kotlin.plugin.serialization' version '$kotlin_version' ... }
第五步:初始化 Supabase 客户端#
每当需要执行 API 调用时,您都可以创建 Supabase 客户端。话虽这么说,建议使用像 Hilt 这样的依赖注入库。
val client = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(Postgrest) }
第六步:创建数据传输对象
1 @Serializable
2data class ProductDto(
3 @SerialName("productid")
4 val productId: String,
5 @SerialName("name")
6 val name: String,
7 @SerialName("description")
8 val description: String,
9 @SerialName("price")
10 val price: Double,
11 @SerialName("image")
12 val image: String,
13 @SerialName("category")
14 val category: String,
15 @SerialName("nutrition")
16 val nutrition: String,
17 @SerialName("_id")
18 val _id: Int,
19)
第七步:创建一个domain 对象#
这种对象将被视图消耗。
data class Product( val productId: String, val name: String, val description: String, val price: Double, val image: String, val category: String, val nutrition: String, val _id: Int, )
第八步:从应用程序查询数据
创建存储库以与数据源交互。
interface ProductRepository { fun getProducts(): List<ProductDto> } class ProductRepositoryImpl @Inject constructor( private val postgrest: Postgrest, ) : ProductRepository { override suspend fun getProducts(): List<ProductDto> { val result = client.postgrest["products"] .select().decodeList<ProductDto>() // Handle result data for next step return result } }
第九步:创建一个模块来提供存储库
使用Hilt进行依赖注入。
InstallIn(SingletonComponent::class) @Module abstract class RepositoryModule { @Binds abstract fun bindProductRepository(impl: ProductRepositoryImpl): ProductRepository }
第十步:从协程范围内的 ViewModel 获取数据#
添加 @Inject 注释以在 ViewModel 中使用存储库。
class ProductListViewModel @Inject constructor(
private val productRepository: ProductRepository
) : ViewModel() {
private val _productList = MutableStateFlow<List<Product>?>(listOf())
val productList: Flow<List<Product>?> = _productList
init {
getProducts()
}
fun getProducts() {
viewModelScope.launch {
val products = productRepository.getProducts()
_productList.emit(products?.map { it -> it.asDomainModel() })
}
}
private fun ProductDto.asDomainModel(): Product {
return Product(
productId = this.productId,
name = this.name,
price = this.price,
image = this.image,
description = this.description,
category = this.category,
nutrition = this.nutrition,
_id = this._id
)
}
第十步:观察可组合项中的数据
@Composable fun ProductListScreen( modifier: Modifier = Modifier, navController: NavController, viewModel: ProductListViewModel = hiltViewModel(), ) { val productList = viewModel.productList.collectAsState(initial = listOf()).value if (!productList.isNullOrEmpty()) { LazyColumn( modifier = modifier.padding(24.dp), contentPadding = PaddingValues(5.dp) ) { items(productList) { item -> ProductListItem( product = item, modifier = modifier, onClick = { navController.navigate( ProductDetailsDestination.createRouteWithParam( item.id ) ) }, ) } } } }