I'm using DataStore, and after I create or update an item and save it to the DataStore, I just see it pending in the logs. Nothing else happens and I see no changes in DynamoDB. It can't sync to the the remote DynamoDB database behind AppSync.
2020-09-16 11:35:23.512 23685-23812/com.spendlee.dev I/amplify:aws-datastore: Successfully enqueued PendingMutation{mutatedItem=Profile
Here's my code:
try {
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.addPlugin(AWSApiPlugin())
Amplify.addPlugin(AWSDataStorePlugin())
Amplify.addPlugin(AWSS3StoragePlugin())
Amplify.configure(applicationContext)
Log.i("first Initialization", "Initialized Amplify")
} catch (e: AmplifyException) {
Log.e("first Initialization", "Could not initialize Amplify", e)
}
```kotlin
private fun createProfile(subId: String, spendIee: String, status: String) {
viewModelScope.launch(Dispatchers.IO) {
Amplify.DataStore.query(
Profile::class.java,
Where.id("dummy-query-to-make-datastore-wake-the-**-up"),
{
val profile = Profile.builder()
.username(subId)
.spendleeId(spendIee)
.id(subId)
.state(status)
.avatarImage(null)
.build()
Amplify.DataStore.save(profile,
{ result ->
resCreateProfile.postValue(ResponseHelper.success(result.item()))
observeProfile()
},
{ error ->
resCreateProfile.postValue(
ResponseHelper.error(
error.cause?.message.toString(),
null
)
)
}
)
},
{
Log.i("MyAmplifyApp", "it.cause?.message?.toString()")
}
)
}
}
fun changeProfile(subId: String, spendIee: String, status: String) {
viewModelScope.launch(Dispatchers.IO) {
Amplify.DataStore.query(
Profile::class.java,
Where.id(subId),
{ matches ->
if (matches.hasNext()) {
val original = matches.next()
val edited = original.copyOfBuilder()
.spendleeId(spendIee)
.state(status)
.build()
Amplify.DataStore.save(edited,
{
Log.i("MyAmplifyApp", "Updated a post.")
},
{
Log.e("MyAmplifyApp", "Update failed.", it)
}
)
}
},
{ error ->
Log.e("MyAmplifyApp", error.cause?.message, error)
}
)
}
}
Here's my schema:
```graphql
enum LogEntryType {
DEBUG
INFO
WARNING
ERROR
}
type LogEntry
@model
@key(name: "byUsername", fields: ["username"], queryField: "logEntriesByUsername")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
type: String!
appVersion: String
appBuild: String
file: String
line: Int
message: String
data: String
_ttl: Float
}
enum AdminRequestState {
REQUESTED
PROCESSING
ERROR
DONE
}
type AdminRequest
@model
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
requestType: String!
_ttl: Float
}
type Merchant
@model
@auth(
rules: [
{ allow: groups, groups: ["appuser"], operations: [read] }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
merchantId: String!
other: String!
description: String!
address: String!
phoneNumber: String!
logo: String
}
type Category
@model
@auth(
rules: [
{ allow: groups, groups: ["appuser"], operations: [read] }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
name: String!
}
type Currency
@model
@auth(
rules: [
{ allow: groups, groups: ["appuser"], operations: [read] }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
symbol: String!
quotedAt: Int!
rate: Float!
}
type TaxItem
@model
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
name: String!
amount: Float!
percent: Float!
# receipt: Receipt! @connection
}
enum ReceiptState {
CREATED
UPLOADING
EXPORTING
POSTPONED
EXPORTED
UPLOADED
SCANNING
READY
ERROR
}
type Receipt
@model
@key(name: "byUsername", fields: ["username"], queryField: "receiptsByUsername")
@key(name: "byState", fields: ["state"], queryField: "receiptsByState")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
state: String
isFavorite: Boolean
viewed: Boolean
error: String
dateTime: AWSDateTime
receiptDate: AWSDateTime
emailDocument: String
receiptImage: String
receiptRawText: String
receiptRawData: String
merchant: String
lineItems: AWSJSON
amount: Float
taxTotal: Float
subTotalAmount: Float
tipAmount: Float
total: String
}
enum ReceiptExportState {
REQUESTED
READY
ERROR
}
type ReceiptExport
@model
@key(name: "byReceipt", fields: ["receipt"], queryField: "receiptExportsByReceipt")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
receipt: ID!
state: String
url: String
error: String
}
enum ProfileState {
CHANGE
ACCEPT
INVALID
DUPLICATE
OK
CONFIRMED
}
type Profile
@model
@key(name: "byUsername", fields: ["username"], queryField: "profilesByUsername")
@key(name: "bySpendleeId", fields: ["spendleeId"], queryField: "profilesBySpendleeId")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID! # username
username: ID!
state: String
spendleeId: String!
avatarImage: String
scansPerDay: Int
}
enum SpendSummaryType {
YEAR
MONTH
WEEK
DAY
}
enum SpendSummaryState {
REQUESTED
PROCESSING
ERROR
DONE
}
type SpendSummary3
@model
@key(name: "byUsername", fields: ["username"], queryField: "spendSummary3sByUsername")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
type: String!
year: String!
month: String
day: String
state: String!
error: String
total: Float
numberOfReceipts: Int
_ttl: Float
}
type EventType
@model
@key(name: "byEventName", fields: ["name"], queryField: "eventTypeByName")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID
name: String!
description: String
subscribers: String
}
type DailyScan
@model
@key(name: "byDateAndUser", fields: ["date", "username"], queryField: "scansByNameAndDate")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
date: AWSDateTime
username: ID
currentScansPerDayLimit: Int! # limit which was active on that date
currentDayScans: Int! # scans done on that day so far
}
type OverLimitDailyScans
@model
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID!
}
type ThirdPartyApi
@model
@key(name: "byApiName", fields: ["name"], queryField: "apiByName")
@auth(
rules: [
{ allow: public, provider: apiKey }
{ allow: owner, ownerField: "username" }
{ allow: groups, groups: ["appadmin"], operations: [create, update, read, delete] }
]
) {
id: ID!
username: ID
name: String! # URL domain?
description: String
billingPeriodDays: Int!
billingPeriodStartDate: AWSDateTime!
maxCallsPerBillingPeriod: Int # optional?
threshold: Float
notificationSent: Boolean! # reset it monthly! false if threshold == 0
billingPeriodBeginningBalance: Int # balance in number of calls
currentBillingPeriodCalls: Int # reset every billing to 0
}
Here's my amplifyconfiguration.json:
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"api": {
"plugins": {
"awsAPIPlugin": {
"spendleeenveapi": {
"endpointType": "GraphQL",
"endpoint": "https://REDACTED_BY_JAMESON.appsync-api.us-east-1.amazonaws.com/graphql",
"region": "us-east-1",
"authorizationType": "AMAZON_COGNITO_USER_POOLS"
}
}
}
},
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"UserAgent": "aws-amplify/cli",
"Version": "0.1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "us-east-1:REDACTED_BY_JAMESON",
"Region": "us-east-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-1_REDACTED_BY_JAMESON",
"AppClientId": "xxxxxxxxxxxxxxxxxxxxxxxxx",
"AppClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Region": "us-east-1"
}
},
"Auth": {
"Default": {
"authenticationFlowType": "USER_SRP_AUTH"
}
},
"S3TransferUtility": {
"Default": {
"Bucket": "REDACTED_BY_JAMESON",
"Region": "us-east-1"
}
},
"AppSync": {
"Default": {
"ApiUrl": "https://REDACTED_BY_JAMESON.appsync-api.us-east-1.amazonaws.com/graphql",
"Region": "us-east-1",
"AuthMode": "AMAZON_COGNITO_USER_POOLS",
"ClientDatabasePrefix": "spendleeenveapi_AMAZON_COGNITO_USER_POOLS"
}
},
"PinpointAnalytics": {
"Default": {
"AppId": "REDACTED_BY_JAMESON",
"Region": "us-east-1"
}
},
"PinpointTargeting": {
"Default": {
"Region": "us-east-1"
}
}
}
}
},
"storage": {
"plugins": {
"awsS3StoragePlugin": {
"bucket": "REDACTED_BY_JAMESON",
"region": "us-east-1",
"defaultAccessLevel": "guest"
}
}
},
"analytics": {
"plugins": {
"awsPinpointAnalyticsPlugin": {
"pinpointAnalytics": {
"appId": "REDACTED_BY_JAMESON",
"region": "us-east-1"
},
"pinpointTargeting": {
"region": "us-east-1"
}
}
}
}
}
Here are some additional logs:
2020-09-17 14:44:48.499 11787-11787/com.spendlee.dev I/first聽Initialization: Initialized Amplify
2020-09-17 14:44:53.268 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: PersistentModelVersion
2020-09-17 14:44:53.334 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: LastSyncMetadata
2020-09-17 14:44:53.408 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: ModelMetadata
2020-09-17 14:44:53.483 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: PersistentRecord
2020-09-17 14:44:53.571 11787-11935/com.spendlee.dev I/amplify:aws-datastore: DataStore orchestrator transitioning states. Current mode = STOPPED, target mode = LOCAL_ONLY.
2020-09-17 14:44:53.574 11787-11935/com.spendlee.dev I/amplify:aws-datastore: Starting to observe local storage changes.
2020-09-17 14:44:53.586 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: SpendSummary3
2020-09-17 14:44:53.707 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: LogEntry
2020-09-17 14:44:53.831 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: Profile
2020-09-17 14:44:53.979 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: Receipt
2020-09-17 14:44:54.117 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: LogEntry
2020-09-17 14:44:54.244 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: PersistentRecord
2020-09-17 14:44:54.368 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: SpendSummary3
2020-09-17 14:44:54.799 11787-11935/com.spendlee.dev W/amplify:aws-datastore: Failed to start observing storage changes.
2020-09-17 14:44:54.833 11787-11944/com.spendlee.dev D/amplify:aws-datastore: Orchestrator completed a transition
2020-09-17 14:44:54.891 11787-11943/com.spendlee.dev D/amplify:aws-datastore: Querying item for: PersistentModelVersion
2020-09-17 14:44:55.097 11787-11936/com.spendlee.dev D/amplify:aws-datastore: Writing data to table for: PersistentModelVersion{id='1ae1b4d0-7894-4f23-831e-ccf6c8439e1c', version='643d6e39-8eb6-3709-8fcd-bbd175ecebc2'}
2020-09-17 14:44:55.329 11787-11936/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 1ae1b4d0-7894-4f23-831e-ccf6c8439e1c
2020-09-17 14:44:55.343 11787-11936/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 643d6e39-8eb6-3709-8fcd-bbd175ecebc2
2020-09-17 14:44:48.499 11787-11787/com.spendlee.dev I/first聽Initialization: Initialized Amplify
2020-09-17 14:44:53.268 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: PersistentModelVersion
2020-09-17 14:44:53.334 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: LastSyncMetadata
2020-09-17 14:44:53.408 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: ModelMetadata
2020-09-17 14:44:53.483 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: PersistentRecord
2020-09-17 14:44:53.571 11787-11935/com.spendlee.dev I/amplify:aws-datastore: DataStore orchestrator transitioning states. Current mode = STOPPED, target mode = LOCAL_ONLY.
2020-09-17 14:44:53.574 11787-11935/com.spendlee.dev I/amplify:aws-datastore: Starting to observe local storage changes.
2020-09-17 14:44:53.586 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: SpendSummary3
2020-09-17 14:44:53.707 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: LogEntry
2020-09-17 14:44:53.831 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: Profile
2020-09-17 14:44:53.979 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating table: Receipt
2020-09-17 14:44:54.117 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: LogEntry
2020-09-17 14:44:54.244 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: PersistentRecord
2020-09-17 14:44:54.368 11787-11936/com.spendlee.dev I/amplify:aws-datastore: Creating index for table: SpendSummary3
2020-09-17 14:44:54.799 11787-11935/com.spendlee.dev W/amplify:aws-datastore: Failed to start observing storage changes.
java.lang.RuntimeException: AmplifyException {message=Error in querying the model., cause=java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference, recoverySuggestion=See attached exception for details.}
at io.reactivex.rxjava3.internal.util.ExceptionHelper.wrapOrThrow(ExceptionHelper.java:46)
at io.reactivex.rxjava3.internal.observers.BlockingMultiObserver.blockingAwait(BlockingMultiObserver.java:145)
at io.reactivex.rxjava3.core.Completable.blockingAwait(Completable.java:1490)
at com.amplifyframework.datastore.syncengine.Orchestrator.startObservingStorageChanges(Orchestrator.java:248)
at com.amplifyframework.datastore.syncengine.Orchestrator.transitionToLocalOnly(Orchestrator.java:212)
at com.amplifyframework.datastore.syncengine.Orchestrator.transitionCompletable(Orchestrator.java:169)
at com.amplifyframework.datastore.syncengine.Orchestrator.start(Orchestrator.java:139)
at com.amplifyframework.datastore.AWSDataStorePlugin.initialize(AWSDataStorePlugin.java:226)
at com.amplifyframework.core.category.Category.initialize(Category.java:120)
at com.amplifyframework.core.Amplify.lambda$beginInitialization$0(Amplify.java:163)
at com.amplifyframework.core.-$$Lambda$Amplify$EB8h7rBH19uqUcPr0ZtYS0ww0r4.run(Unknown Source:4)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: AmplifyException {message=Error in querying the model., cause=java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference, recoverySuggestion=See attached exception for details.}
at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.lambda$query$4$SQLiteStorageAdapter(SQLiteStorageAdapter.java:397)
at com.amplifyframework.datastore.storage.sqlite.-$$Lambda$SQLiteStorageAdapter$rGner20-W7t2tJu4yCrrZwlquWE.run(Unknown Source:10)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)聽
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)聽
at java.lang.Thread.run(Thread.java:919)聽
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.getQueryAllCursor(SQLiteStorageAdapter.java:794)
at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.lambda$query$4$SQLiteStorageAdapter(SQLiteStorageAdapter.java:372)
at com.amplifyframework.datastore.storage.sqlite.-$$Lambda$SQLiteStorageAdapter$rGner20-W7t2tJu4yCrrZwlquWE.run(Unknown Source:10)聽
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)聽
at java.util.concurrent.FutureTask.run(FutureTask.java:266)聽
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)聽
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)聽
at java.lang.Thread.run(Thread.java:919)聽
2020-09-17 14:44:54.833 11787-11944/com.spendlee.dev D/amplify:aws-datastore: Orchestrator completed a transition
2020-09-17 14:44:54.891 11787-11943/com.spendlee.dev D/amplify:aws-datastore: Querying item for: PersistentModelVersion
2020-09-17 14:44:55.097 11787-11936/com.spendlee.dev D/amplify:aws-datastore: Writing data to table for: PersistentModelVersion{id='1ae1b4d0-7894-4f23-831e-ccf6c8439e1c', version='643d6e39-8eb6-3709-8fcd-bbd175ecebc2'}
2020-09-17 14:44:55.329 11787-11936/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 1ae1b4d0-7894-4f23-831e-ccf6c8439e1c
2020-09-17 14:44:55.343 11787-11936/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 643d6e39-8eb6-3709-8fcd-bbd175ecebc2
2020-09-17 14:46:59.981 11787-12373/com.spendlee.dev W/om.spendlee.de: Verification of void com.spendlee.dev.viewModels.AuthViewModel$callAuthSession$1$1.accept(com.amplifyframework.auth.AuthSession) took 145.547ms
2020-09-17 14:47:00.721 11787-12373/com.spendlee.dev I/amplify:aws-datastore: DataStore orchestrator transitioning states. Current mode = STOPPED, target mode = LOCAL_ONLY.
2020-09-17 14:47:00.721 11787-12373/com.spendlee.dev I/amplify:aws-datastore: Starting to observe local storage changes.
2020-09-17 14:47:00.738 11787-12685/com.spendlee.dev D/amplify:aws-datastore: Querying item for: PersistentRecord
2020-09-17 14:47:00.782 11787-12685/com.spendlee.dev I/amplify:aws-datastore: Now observing local storage. Local changes will be enqueued to mutation outbox.
2020-09-17 14:47:00.785 11787-11944/com.spendlee.dev D/amplify:aws-datastore: Orchestrator completed a transition
2020-09-17 14:47:00.797 11787-12685/com.spendlee.dev D/amplify:aws-datastore: Querying item for: Profile
2020-09-17 14:47:00.801 11787-11944/com.spendlee.dev D/amplify:aws-datastore: Orchestrator completed a transition
2020-09-17 14:47:00.812 11787-12686/com.spendlee.dev D/amplify:aws-datastore: Writing data to table for: Profile {id=3b2fac96-ea30-40c3-81bb-d1e3f7fd263d, username=3b2fac96-ea30-40c3-81bb-d1e3f7fd263d, state=OK, spendleeId=azadehsoli+logger, avatarImage=null, scansPerDay=null}
2020-09-17 14:47:00.816 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 3b2fac96-ea30-40c3-81bb-d1e3f7fd263d
2020-09-17 14:47:00.816 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = null
2020-09-17 14:47:00.817 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = null
2020-09-17 14:47:00.817 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = azadehsoli+logger
2020-09-17 14:47:00.817 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = OK
2020-09-17 14:47:00.818 11787-12686/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 3b2fac96-ea30-40c3-81bb-d1e3f7fd263d
2020-09-17 14:47:00.883 11787-12685/com.spendlee.dev D/amplify:aws-datastore: Writing data to table for: Record{id='2bd9012b-f916-11ea-a000-2171c644ddc6', containedModelId='3b2fac96-ea30-40c3-81bb-d1e3f7fd263d', serializedMutationData='{"classOfMutatedItem":"com.amplifyframework.datastore.generated.model.Profile","mutatedItem":{"id":"3b2fac96-ea30-40c3-81bb-d1e3f7fd263d","spendleeId":"azadehsoli+logger","state":"OK","username":"3b2fac96-ea30-40c3-81bb-d1e3f7fd263d"},"mutationId":2bd9012b-f916-11ea-a000-2171c644ddc6,"mutationType":"CREATE","predicate":{"_type":"ALL"}}', containedModelClassName='com.amplifyframework.datastore.generated.model.Profile'}
2020-09-17 14:47:00.886 11787-12685/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 2bd9012b-f916-11ea-a000-2171c644ddc6
2020-09-17 14:47:00.892 11787-12685/com.spendlee.dev V/amplify:aws-datastore: Could not find getContainedModelClassName() on com.amplifyframework.datastore.syncengine.PendingMutation$PersistentRecord. Fallback to direct field access.
2020-09-17 14:47:00.893 11787-12685/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = com.amplifyframework.datastore.generated.model.Profile
2020-09-17 14:47:00.895 11787-12685/com.spendlee.dev V/amplify:aws-datastore: Could not find getContainedModelId() on com.amplifyframework.datastore.syncengine.PendingMutation$PersistentRecord. Fallback to direct field access.
2020-09-17 14:47:00.895 11787-12685/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = 3b2fac96-ea30-40c3-81bb-d1e3f7fd263d
2020-09-17 14:47:00.898 11787-12685/com.spendlee.dev V/amplify:aws-datastore: Could not find getSerializedMutationData() on com.amplifyframework.datastore.syncengine.PendingMutation$PersistentRecord. Fallback to direct field access.
2020-09-17 14:47:00.898 11787-12685/com.spendlee.dev V/amplify:aws-datastore: SQLiteStorageAdapter.bindValueToStatement(..., value = {"classOfMutatedItem":"com.amplifyframework.datastore.generated.model.Profile","mutatedItem":{"id":"3b2fac96-ea30-40c3-81bb-d1e3f7fd263d","spendleeId":"azadehsoli+logger","state":"OK","username":"3b2fac96-ea30-40c3-81bb-d1e3f7fd263d"},"mutationId":2bd9012b-f916-11ea-a000-2171c644ddc6,"mutationType":"CREATE","predicate":{"_type":"ALL"}}
2020-09-17 14:47:00.904 11787-12685/com.spendlee.dev I/amplify:aws-datastore: Successfully enqueued PendingMutation{mutatedItem=Profile {id=3b2fac96-ea30-40c3-81bb-d1e3f7fd263d, username=3b2fac96-ea30-40c3-81bb-d1e3f7fd263d, state=OK, spendleeId=azadehsoli+logger, avatarImage=null, scansPerDay=null}, classOfMutatedItem=class com.amplifyframework.datastore.generated.model.Profile, mutationType=CREATE, mutationId=2bd9012b-f916-11ea-a000-2171c644ddc6, predicate=MatchAllQueryPredicate}
Thanks @azisoli! This looks like a bug, to me:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.getQueryAllCursor(SQLiteStorageAdapter.java:794)
at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.lambda$query$4$SQLiteStorageAdapter(SQLiteStorageAdapter.java:372)
at com.amplifyframework.datastore.storage.sqlite.-$$Lambda$SQLiteStorageAdapter$rGner20-W7t2tJu4yCrrZwlquWE.run(Unknown Source:10)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
@jamesonwilliams yes it seems a bug.
Hi @azisoli, in the code sample above, I see this line is commented out:
// Amplify.addPlugin(AWSApiPlugin())
Without the AWSApiPlugin(), DataStore will operate in a local only mode, so it won't be syncing to the backend. If you uncomment that, it should sync to the backend.
@richardmcclellan i did it and i have this now but still no chnges in database it just change version but not the other fields . log is attached.
lasone.txt
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.addPlugin(AWSApiPlugin())
Amplify.addPlugin(AndroidLoggingPlugin(LogLevel.VERBOSE))
Amplify.addPlugin(AWSDataStorePlugin())
Amplify.addPlugin(AWSS3StoragePlugin())
Amplify.configure(applicationContext)
Hey @azisoli, given that your models are protected with the @auth directive, the initial DataStore initialization fails if no one is signed in yet, as seen in your logs. This is expected, but there are a couple tricks to making sure that DataStore gets re-initialized after sign in. I would suggest doing the following steps:
Here's some sample code for doing this:
Amplify.Auth.signIn(USERNAME, PASSWORD, (AuthSignInResult result) -> {
Amplify.DataStore.query(Todo.class, result -> { /* ignore this result */ }, error -> { });
Amplify.Hub.subscribe(HubChannel.DATASTORE,
hubEvent -> DataStoreChannelEventName.READY.equals(hubEvent.getName()),
hubEvent -> Amplify.DataStore.query(Todo.class, result -> { /* expect the actual results here */ }, error -> { })
);
});
In regards to the error that @jamesonwilliams called out:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
I suspect we might have a bug caused by calling DataStore.save before DataStore is fully initialized. Waiting for the READY hub event as described may resolve this issue.
In the future, we'll consider ways to improve this, so there aren't so many steps required.
@richardmcclellan i need to call Amplify.Auth.fetchAuthSession after signin ,can i call it in hub event and in result of that i call save on datastore?
@richardmcclellan How is this code suppose to work? For me, the first part is happening:
hubEvent -> DataStoreChannelEventName.READY.equals(hubEvent.getName()),
But the second part never happens:
hubEvent -> Amplify.DataStore.query(Todo.class, result -> { /* expect the actual results here */ }, error -> { })
Here are my logs: hub.txt
@azisoli It sounds like DataStoreChannelEventName.READY.equals(hubEvent.getName()) is evaluating to false. This will occur if there are events on the Hub, but none of them are the READY event. Or, in other words, your DataStore instance is never becoming ready.
It shows as ready:

Here's my code. Does it look right?
private fun callSignIn(userName: String, password: String) {
viewModelScope.launch(Dispatchers.IO) {
Amplify.Auth.signIn(userName, password,
{ result ->
//signInRes.postValue(ResponseHelper.success(result.isSignInComplete))
Amplify.DataStore.query(Profile::class.java,{},{})
Amplify.Hub.subscribe(
HubChannel.DATASTORE,
{ hubEvent ->
DataStoreChannelEventName.READY.equals(hubEvent.name) },
{ hubEvent->
Amplify.Auth.fetchAuthSession(
{ result ->
val cognitoAuthSession = result as AWSCognitoAuthSession
when (cognitoAuthSession.identityId.type) {
AuthSessionResult.Type.SUCCESS -> {
val place = userName.indexOf("@")
val spendIee: String = userName.substring(0, place )
createProfile(cognitoAuthSession.userSub.value.toString(),spendIee,
ProfileState.OK.toString())
}
AuthSessionResult.Type.FAILURE ->resCreateProfile.postValue(ResponseHelper.error("problem happened in sigIn process", null))
}
},
{ error -> resCreateProfile.postValue(ResponseHelper.error("problem happened in sigIn process", null)) })
}
)
},
{ error ->
resCreateProfile.postValue(ResponseHelper.error("problem happened in sigIn process", null)) }
)
}
}
@azisoli @richardmcclellan Oh, derp. We're comparing a String to an enum.
This line:
DataStoreChannelEventName.READY.equals(hubEvent.getName())
Needs to become:
DataStoreChannelEventName.READY.toString().equals(hubEvent.getName())
@azisoli @richardmcclellan @rjuliano Where did we end up on this one? Sounds like maybe a combination of https://github.com/aws-amplify/amplify-android/issues/853, and the need to wait for sign-in, via Hub?
We're tracking two fixes that appear to be related to issues reported here.
1 - #853: Adding some safeguards around sync engine startup. This addresses the issue where the startup sequence is getting triggered multiple times.
2 - #854: Derive the subscription startup timeout from the number of models. Currently, the subscription initialization may timeout because it doesn't take into account the number of models in the schema.
Both of these prevent the sync process from pushing local updates to the cloud and pulling cloud updates to local
@rjuliano Awesome! Shall we close this one, and focus on #853 #854? @azisoli does that sound like a plan?
Yes sure
I'm running into the same issue. All versions starting from 1.3.0 and up are causing issues. If I checked correctly, above mentioned issues are not released ? Can I see when this is planned to be released ?
Thanks
@woutermilants This issue has been closed. Can you please open a new issue with details about your code, configuration, and specific errors, with associated logs. Please follow up on #853 and #854 if you are encountering the specific errors referenced in those issues.