Using Cognito user pools as my auth method, I am able to login verified users through the app and then those authenticated users can write to DynamoDB with an AppSync mutation just fine. The S3Object info is also populated in Dynamo as a JSON string like so:
"pdf": "{\"s3\":{\"key\":\"6_A_2018-04-26_etc.pdf\",\"bucket\":\"#####\",\"region\":\"us-west-2\"}}"
The request mapping template for the create mutation in AppSync is:
{
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"id" : { "S" : "${util.autoId()}" }
},
#set( $attribs = $util.dynamodb.toMapValues($ctx.args.input) )
#if($util.isNull($ctx.args.input.pdf.version))
#set( $attribs.pdf = $util.dynamodb.toS3Object($ctx.args.input.pdf.key, $ctx.args.input.pdf.bucket, $ctx.args.input.pdf.region))
#else
#set( $attribs.pdf = $util.dynamodb.toS3Object($ctx.args.input.pdf.key, $ctx.args.input.pdf.bucket, $ctx.args.input.pdf.region, $ctx.args.input.pdf.version))
#end
"attributeValues" : $util.toJson($attribs)
}
Response mapping template:
$util.toJson($ctx.result)
pdf (S3Object) request mapping template (I've tried both the version and empty payload {} None resolver and this one):
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
## Provide a query expression. **
"expression": "id = :id",
"expressionValues" : {
":id" : {
"S" : "${ctx.args.id}"
}
}
}
}
Response mapping template for pdf:
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.pdf))
But NO S3 OBJECT is created in the bucket. However, if I use S3TransferUtility.default() on its own to send the upload request, it works perfectly fine, so I must have the correct permissions set for PutObject (also GetObject and ListObjects as I can also list / download objects from the bucket with s3TransferUtility).
Since AppSync is supposed to be using S3TransferUtility.default(), does anyone have any ideas for why the upload is not happening automatically? My view controller is dismissed afterwards, like in the tutorials, but that shouldn't be a problem because I am using the optimistic response method and it is not throwing any errors. I also tried simply using the perform mutation function without the optimistic response. Also I've tried NOT dismissing the view controller and waiting. Still no upload to S3, but the write to Dynamo never fails! Even optimistically updates to Dynamo when I return from airplane mode. File size for PDF doc is ~250KB.
By the way, the following also does work after pulling in my items from Dynamo using a graphql listAll query and only after uploading to S3 manually so it's actually in the bucket (I'm missing some optional chaining I am at work this part is from memory):
let s3Object = S3Object.init(snapshot: selectedItem.pdf.snapshot)
appSyncClient.s3ObjectManager.download(s3Object: s3Object, toURL: url) { ifSuccess, error in
})
Something like that. It does download the object, but it's because I called it manually. To be fair, I'm actually not sure what the intended functionality of a retrieved S3Object from a graphql query is (is it supposed to download it automatically...? Do I have access to that item as anything other than a AllPostsQuery.Data.ListPost.Item.Pdf or are we meant to download ourselves using the bucket, key, region as I have?) That's off topic, I suppose.
Any help would be much appreciated I'm really banging my head against the wall on this one.
EDIT: More / updated info here on the AWS Forums
EDIT: GitHub issue has elicited a response from AWS and they are looking into it