aws-mobile-appsync-sdk-ios icon indicating copy to clipboard operation
aws-mobile-appsync-sdk-ios copied to clipboard

Subscription AWSJSON fields are double encoded

Open mnightingale opened this issue 4 years ago • 4 comments

Describe the bug AWSJSON fields in subscription payloads are double encoded, making them inconsistent with the behaviour of mutations and queries.

To Reproduce Create a backend using the Amplify CLI and deploy the following schema:

type Example 
  @model {
  id: ID!
  extra: AWSJSON
}

Create a subscription

do {
    subscriptionWatcher = try appSyncClient.subscribe(subscription: OnCreateExampleSubscription(), resultHandler: { (result, transaction, error) in
        if let result = result {
            guard var created = result.data?.onCreateExample else {
                return
            }
            
            print("Subscription:")
            print(created.extra)
        } else if let error = error {
          print(error.localizedDescription)
        }
    })
} catch {
    print("Error starting subscription.")
}

Send a mutation and a fetch request (wait for subscription to be active, use two clients, use the console, DispatchQueue.main.asyncAfter, etc.)

// Mutate
appSyncClient.perform(mutation: CreateExampleMutation(input: CreateExampleInput(
    id: UUID().uuidString,
    extra: String(data: try! JSONEncoder().encode(["key": "value"]), encoding: .utf8)
))) { (result, error) in
    guard var created = result?.data?.createExample else {
        return
    }

    print("Created:")
    print(created.extra)
    
    // Fetch
    self.appSyncClient.fetch(query: ListExamplesQuery()) { (result, error) in
        result?.data?.listExamples?.items?.forEach { fetched in
            print("Fetched:")
            print(fetched?.extra)
        }
    }
}

Output

Created:
Optional("{\"key\":\"value\"}")
Fetched:
Optional("{\"key\":\"value\"}")
WebsocketDidReceiveMessage - {"id":"2215B2DF-673C-499C-9FC4-F9897F06EBED","type":"data","payload":{"data":{"onCreateExample":{"__typename":"Example","id":"940E1E88-0177-4B7B-A1EA-3581890AC35D","extra":"\"{\\\"key\\\":\\\"value\\\"}\""}}}}
Subscription:
Optional("\"{\\\"key\\\":\\\"value\\\"}\"")

As you can see the mutation response and the query are consistent but the subscription returns a double json encoded string.

Expected behavior I would expect all three (created/subscription/fetch) to return the same data, instead I'm required to decode the json field twice for subscriptions.

I'm not really sure how fixable this is, I guess it's an issue with the backend that writes to the subscription, but I don't know if that can be fixed without breaking existing clients that are expecting JSON(JSON)? Perhaps the code Amplify generates could handle it (OnCreateExampleSubscription.Data.OnCreateExample)

Environment(please complete the following information):

  • AppSync SDK Version: 3.0.2
  • Dependency Manager: Cocoapods
  • Swift Version : 5.1

Device Information (please complete the following information):

  • Device: Simulator
  • iOS Version: iOS 13.4

mnightingale avatar Apr 01 '20 09:04 mnightingale

For what it's worth, I have found this same behavior. So +1

airstance avatar May 08 '20 06:05 airstance

Same here. So +1

marekskalik avatar May 21 '20 07:05 marekskalik

Same issue here! What is the fix from Amazon?

kopecn avatar May 14 '22 23:05 kopecn

Thanks for following up on this issue. Our team is investigating the issue and will provide an update on the issue.

harsh62 avatar May 16 '22 16:05 harsh62

Thank you for opening this issue. AWS AppSync SDK for iOS entered maintenance mode in September 2023 and will receive no further updates as of September 2024.

Please use Amplify Swift going forward. For information on upgrading to Amplify Swift, refer to the Upgrade from AppSync SDK documentation.

atierian avatar Dec 07 '23 20:12 atierian