aws-amplify / amplify-android

The fastest and easiest way to use AWS from your Android app.
https://docs.amplify.aws/lib/q/platform/android/
Apache License 2.0
231 stars 108 forks source link

aws-logging-cloudwatch: Emitted logs not being deleted from local database #2772

Closed hirengosalia86 closed 1 month ago

hirengosalia86 commented 1 month ago

Before opening, please confirm:

Language and Async Model

Kotlin

Amplify Categories

Not applicable

Gradle script dependencies

```groovy // Put output below this line implementation("com.amplifyframework:core:2.15.0") implementation("com.amplifyframework:aws-logging-cloudwatch:2.15.0") ```

Environment information

``` ------------------------------------------------------------ Gradle 7.6.1 ------------------------------------------------------------ Build time: 2023-02-24 13:54:42 UTC Revision: 3905fe8ac072bbd925c70ddbddddf4463341f4b4 Kotlin: 1.7.10 Groovy: 3.0.13 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 11.0.22 (Amazon.com Inc. 11.0.22+7-LTS) OS: Mac OS X 14.3.1 x86_64 ```

Please include any relevant guides or documentation you're referencing

No response

Describe the bug

bulkDelete function called in syncLogEventsWithCloudwatch fails on deleteing, when there are more than 1 events. This causes log being duplicated multiple times in cloudwatch

Reproduction steps (if applicable)

No response

Code Snippet

internal suspend fun bulkDelete(eventIds: List<Long>) = withContext(coroutineDispatcher) {
        contentUri
        val whereClause = "${LogEventTable.COLUMN_ID} in (?)" // number of '?' should match count of eventIds.
        database.delete(
            LogEventTable.TABLE_LOG_EVENT,
            whereClause,
            arrayOf(eventIds.joinToString(","))
        )
    }

Log output

``` // Put your logs below this line ```

amplifyconfiguration.json

No response

GraphQL Schema

```graphql // Put your schema below this line ```

Additional information and screenshots

No response

joon-won commented 1 month ago

Hi @hirengosalia86, thank you for your report. Could you provide full log for this issue?

hirengosalia86 commented 1 month ago

Hi @joon-won , there are no log outputs, but as you can see in the bulkDelete function, if there are more than 1 eventIds (1,2,3) there only exists 1 '?' corresponding to this, making it as a string '1,2,3'

hirengosalia86 commented 1 month ago

@joon-won

internal suspend fun bulkDelete(eventIds: List<Long>) = withContext(coroutineDispatcher) {
    contentUri
    if (!eventIds.isEmpty()) {
         val params =  List(eventIds.size, {"?"})
          val whereClause = "${LogEventTable.COLUMN_ID} in (${params.joinToString(",")})"
          database.delete(
              LogEventTable.TABLE_LOG_EVENT,
              whereClause,
              eventIds.toTypedArray()
          )
    }
}

This should fix it.

joon-won commented 1 month ago

Thank you for your reply and suggestion . However will the current code fail when multiple ids are passed? arrayOf() function will make it a string array [1,2,3], and become string when it joins the WHERE clause. Since this is a sqlite in its core, string representation should be working fine. If you were still noticing the deletion failing when you were passing multiple ids, someone in our team will take a look into the issue.

hirengosalia86 commented 1 month ago

Agreed, string representation works fine in sqlite, but above will be arrayOf() on a string. Making it

Delete from <table_name> where <cloumn> in ('1,2,3')

instead of


Delete from <table_name> where <cloumn> in (1, 2, 3)
hirengosalia86 commented 1 month ago

SQL Lite is untyped so it won't produce an error when trying to compare a column against the wrong datatype, instead what you get is a no-op. In order for this method to work as one would expect the ? in the statement would have to be bound to an array and not a string. Yet the android-database-sqlcipher library that's being used here is not capable of binding the ? to an array, it is only capable in binding single value types (see DatabaseUtils.bindObjectToProgram). So the outcome is Delete from <table_name> where <cloumn> in ('1,2,3').

joon-won commented 1 month ago

Thank you for providing your example and explanation, I see the point. I will share this with the team, and look into the issue

joon-won commented 1 month ago

This issue is resolved with Amplify Android 2.16.1 please let us know if the issue persists

github-actions[bot] commented 1 month ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.