既存の amplify appsync 環境を android から使う
既存の物を使う系がでてこなかったので
ここで出た結論としては、amplify とかでつなぎに行く手段はなくて、素の sdk w使ったほうが良いのでは、という話。
さっと検索して、既存を使う場合の新しい騎士児が見つからなければ、sdk 直接でやってみる
schema 生成とかはどうやるのか全然わかっていないけど、 amplify 経由でないとできないとかではないはず
(むしろそっちが少数派?)
client は作成してるけど
/usr/src# amplify codegen --apiId xxxxxxxxxxxxxxx --envName dev
code generation is not configured. Configure it by running
$amplify codegen add
やっぱりだめそう
# amplify pull --apiId xxxxxxxxxxxxxxxx --envName dev
Pre-pull status:
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |
✔ Successfully pulled backend environment dev from the cloud.
Post-pull status:
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |
root@74469aeb7e13:/usr/src# amplify update api
? Please select from one of the below mentioned services: GraphQL
No AppSync resource to update. Use the "amplify add api" command to update your existing AppSync API.
いろいろ調べましたが、多分すでAndroidアプリ&Sync元データが存在する状況下てAmplifyを使って上手く安全に工数少なくやる方法はないと思います。
ここの主張とは現段階だと一致してそう
↑を流していく
スキーマ定義の配置
が、どこに何を置くのかがいまいちはっきりとしない
aws から export してきた schema.json なのか、xxx.graphql
のファイルなのか
ここの構成が近そう
見た感じ、 schema.json
と同じディレクトリに xxx.graphql
を設置してる
ので、これを参考にやってみる
xxx.graphql
に
# this is an auto generated file. This will be overwritten
こう書いてあるので、なんか使って生成されてる
検索したらでてくるかな
でてこなかった
でてこなかった
schema.graphql
を aws のページから生成してみる
schema.graphql
を aws のページから生成してみる
できrてるのかよくわからんけども、認証してデータ取得まで真似してやってみる
やりたいことがちょっとずれてた
やりたいのは 既存の appsync 環境を新しい client から使うこと、なんだけれど、
既存環境は amplify を使って 作成されている
しらべてみると、amplify pull
が使えるらしいので、
amplify pull --appId xxxxxx --envName xxxx
これをやってみた
コマンド実行には成功したけど、
amplify status
してみると、
api の部分が deleted になっていて、そのままだと使えないっぽい
--restore
オプションを使うと、できるっぽい?
amplify pull --appId xxxxxx --envName xxxx --restore
で実行すると、
Api
の Operation
が Delete
から No Change
に変わった
amplify codegen models
だと、model 生成はできないっぽい
amplify add codegen --apiId xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
これは通った
build しても appsync のモデルクラスが取得できない
amplify codegen models
これが通れば生成される気はするけど、
No AppSync API configured. Please add an API
相変わらずこれ
API の設定はしてるのになぜ
team-provider-info.json
を覗いてみたら、apiの記述がない。
どうして
amplify-meta.json
には記述がある
0から amplify で作った appsync のプロジェクトを見ると、
team-provider-info.json
には auth
, api
両方の記述がない
既存の dynamodb は amplify の cfn ではなく、 cdk で管理されていた
amplify にそのまま乗っかるのは無理ってことなのか…?
今日のところはここまで
$ amplify update api
? Please select from one of the below mentioned services: GraphQL
The selected resource is not managed using AWS Cloudformation. Please use the AWS AppSync Console to make updates to your API - XXXXXX
cdk を使ってるとだめ?
1 amplify pull
2 amplify codegen models
3 amplify status'
4 amplify status
5 amplify pull --restore
6 amplify codegen
7 amplify codegen add
8 amplify codegen
9 amplify codegen model
10 amplify codegen models
11 amplify codegen --help
12 amplify codegen types
13 amplify codegen configure
14 amplify codegen codegen
15 amplify codegen types
このあたりで、
root@91e605ce4fc7:/usr/src# amplify codegen configure
? Enter the file name pattern of graphql queries, mutations and subscriptions app/src/main/graphql/**/*.graphql
? Enter maximum statement depth [increase from default if your schema is deeply nested] 3
Codegen configured. Remember to run "amplify codegen" to generate your types and statements.
root@91e605ce4fc7:/usr/src# amplify codegen codegen
✔ Downloaded the schema
✔ Generated GraphQL operations successfully and saved at app/src/main/graphql/com/amazonaws/amplify/generated/graphql
これができるようになった
似た問題っぽい気はする
AWSAppSyncClient を使って、 class は生成するな、ということなのか
別プロジェクトに schema.graphql を持っていって、 @model
とかを追加して、amplify codegen models
して、model のコードを持って返ってきて、実行、としてみたけど、無限のエラーに阻まれて実行できない
諦めて AppSyncClient を使って実装してみる。
ただ、こっちもこっちで
apply plugin: 'com.amazonaws.appsync'
これを書くと落ちるっていう謎のエラーがある
諦めて AppSyncClient を使って実装してみる。
ただ、こっちもこっちで
apply plugin: 'com.amazonaws.appsync'
これを書くと落ちるっていう謎のエラーがある
これをすすめる
これをすすめる
Unable to find method 'org.gradle.api.internal.file.DefaultSourceDirectorySet.<init>(Ljava/lang/String;Ljava/lang/String;Lorg/gradle/api/internal/file/FileResolver;Lorg/gradle/api/internal/file/collections/DirectoryFileTreeFactory;)V'
org.gradle.api.internal.file.DefaultSourceDirectorySet.<init>(Ljava/lang/String;Ljava/lang/String;Lorg/gradle/api/internal/file/FileResolver;Lorg/gradle/api/internal/file/collections/DirectoryFileTreeFactory;)V
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
Re-download dependencies and sync project (requires network)
The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Stop Gradle build processes (requires restart)
Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
そうしたら、ここで謎のエラーに遭遇
これ?
対応してるって書いてる
記事が書かれたときにはまだできなかったけど、リリースがでてできるようになったみたいな感じかな
readme に従って build.gradle を書いて sync, build したけどエラーは出ない
id 'com.amazonaws.appsync'
もちゃんと通ってる
amplify からとってくる前に公式の実行して様子見したほうが良いかも
Next, fetch the schema.json file from the AppSync console and place it alongside the posts.graphql file:
schema.json がいるらしいので、テスト schema で試せない
Next, fetch the schema.json file from the AppSync console and place it alongside the posts.graphql file:
schema.json がいるらしいので、テスト schema で試せない
素直に amplify pull && amplify codegen
で持ってくる
amplify pull
amplify pull --restore
amplify codegen add
これで schema.json
, mutation.graphql
, queries.graphql
, subscritions.graphql
の作成に成功
Now build the project and the generated source files will be available to use within the app. They will not show up in your source directory, but are added in the build path.
build すれば使えるようになるらしい
XXXXXXXXXXXXXXXX\android\app\build\generated\source\appsync\com\amazonaws\amplify\generated\graphql\XXXXXXXXXXXXXX.java:286: {文字化け}
final @Nullable @Nullable List<XXXXXXXXXX> XXXXXXXXXXXXXXX;
Duplicate annotation. The declaration of 'javax.annotation.Nullable' does not have a valid java.lang.annotation.Repeatable annotation
なぜか @Nullable
が二重になった状態で生成されてる
List のところだけ Nullable が二重になってる
この問題っぽい
navigation components と競合してるっぽい?
Hi @micstepper, what is your androidx.navigation version? found for me it fails with 2.3.0-alpha05 but works fine with 2.3.0-alpha04
2.3.0-alpha04
で通った。
良かった
ext.kotlin_version = "1.4.21"
ext.nav_version = "2.3.0-alpha04"
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
// AppSync
classpath 'com.amazonaws:aws-android-sdk-appsync-gradle-plugin:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// navigation components
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
// AWS AppSync SDK
implementation 'com.amazonaws:aws-android-sdk-appsync:3.1.0'
}
依存関係メモ
次これ
val client = AWSAppSyncClient.builder()
.context(context)
.apiKey(BasicAPIKeyAuthProvider(Constants.APPSYNC_API_KEY)) // API Key based authorization
.region(Constants.APPSYNC_REGION)
.serverUrl(Constants.APPSYNC_API_URL)
.build()
これ、 Constants は自分で入れろってことかな
そうっぽい。secrets っぽいのはどこに定義して読んであげれば良いんだろうか
client だから secrets もなにもないか
こっちで書くからわざわざとってくる必要なかった
client を初期化して起動するところまで通った
val client = AWSAppSyncClient.builder()
.context(this)
.awsConfiguration(AWSConfiguration(this))
.build()
ここのところ
package com.example.sample.activity
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.amazonaws.amplify.generated.graphql.ListPostQuery
import com.amazonaws.mobile.config.AWSConfiguration
import com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient
import com.apollographql.apollo.GraphQLCall
import com.apollographql.apollo.api.Response
import com.apollographql.apollo.exception.ApolloException
import com.example.sample.R
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val client = AWSAppSyncClient.builder()
.context(this)
.awsConfiguration(AWSConfiguration(this))
.build()
val query = ListPostQuery.builder().build()
val caller = client.query(query)
caller.enqueue(object : GraphQLCall.Callback<ListPostQuery.Data>() {
override fun onFailure(e: ApolloException) {
Log.e("AppSync", "onFailure: fail to fetch", e)
}
override fun onResponse(response: Response<ListPostQuery.Data>) {
Log.d(
"AppSync",
"onResponse: ${response.data()!!.listPost()!!.items()}"
)
}
})
}
}
これでデータ取得に成功した
(package 名、model 名はダミー)
ここまでできたので、coroutine もいれてみる
これでやる
package com.example.sample.activity
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.amazonaws.amplify.generated.graphql.ListPostQuery
import com.amazonaws.mobile.config.AWSConfiguration
import com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient
import com.apollographql.apollo.GraphQLCall
import com.apollographql.apollo.api.Response
import com.apollographql.apollo.exception.ApolloException
import com.example.sample.R
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val client = AWSAppSyncClient.builder()
.context(this)
.awsConfiguration(AWSConfiguration(this))
.build()
getListPost(client)
}
private fun getListPost(client: AWSAppSyncClient) = MainScope().launch(Dispatchers.Main) {
val result = getListPost(client)
Log.d("MainActivity", "getListPost: $result")
}
}
suspend fun getListPost(client: AWSAppSyncClient): List<ListPostQuery.Item> {
return suspendCoroutine { continuation ->
val query = ListPostQuery.builder().build()
val caller = client.query(query)
caller.enqueue(object : GraphQLCall.Callback<ListPostQuery.Data>() {
override fun onFailure(e: ApolloException) {
throw e
}
override fun onResponse(response: Response<ListPostQuery.Data>) {
// ここでこんなに !! して良いものなのかは不安
val result = response.data()!!.listPost()!!.items()!!
continuation.resume(result)
}
})
}
}
取得成功したので閉じ
別PC で作業するときは、改めて configfile をとってくる必要があった
amplify pull --restore
amplify codegen
これで復活した