0
votes

My iOS app interacts with a google app engine backend. I have the option for user to report an issue. When user enters the text describing the problem and presses the Submit button, I want to start a background upload of the issue description plus logs being collected in the app using CocoaLumberjack.

My current approach (almost working) is as follows. iOS sends a multipart/form-data POST request that contains a String with bug description and log file content (NSData) with each part separated by a boundary. The GAE server is able to successfully decode each part and I am able to see the file content when I print it out using logging.info(). However, when I try to store the file to GCS, I get an error. The code used to store to GCS and error are below.

I have one storage bucket configured and this has class = Durable Reduced Availability.

Can someone point me to what I'm doing wrong (I suspect it is something about how I set up the authorization lists in the GCS container)?

Alternatively, I am all ears if someone has an easier way to solve this problem.

Code used to store into GCS is:

logging.info('Creating file %s\n' % (filename))            
write_retry_params = gcs.RetryParams(initial_delay=0.2,
                              max_delay=5.0,
                              backoff_factor=1.2,
                              max_retry_period=15)

gcs_file = gcs.open(filename,
                'w',
                content_type='text/plain',
                retry_params=write_retry_params)
gcs_file.write(filename=getattr(request, 'fileAttached'))
gcs_file.close()

Error seen in GAE:

ForbiddenError: Expect status [201] from Google Storage. But got status 403. Path: '/var/mobile/Containers/Data/Application/4FB6C1D7-9504-4215-BC25-FC490298EEF6/Library/Caches/Logs/com.apm.smartiothome.chatime%202016-01-20%2008-01.log'. Request headers: {'x-goog-resumable': 'start', 'x-goog-api-version': '2', 'content-type': 'text/plain', 'accept-encoding': 'gzip, *'}. Response headers: {'content-type': 'application/xml; charset=UTF-8', 'content-length': '195', 'vary': 'Origin', 'x-guploader-uploadid': 'AEnB2Uo1b-z2VGlHOnurusG2F9bgKcBVwmYWZrQFG4d4NBrHA_tk9wTPoa4kB1Aici7XP7Z6fNtuSJlGDokUmxtCFAl8aMnXGA'}. Body: "AccessDeniedAccess denied.Caller does not have storage.objects.create access to bucket var.". Extra info: None.

1

1 Answers

0
votes

I opened the menu "IAM & Admin" > Service accounts and copied the "Service account ID" from the row "App Engine default service account". The name was my app followed by "@appspot.gserviceaccount.com".

Next, I opened Storage and click the "..." next to the default bucket > Edit bucket permissions. I added the service account as a user with Writer access.