Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOLD for payment 2023-09-06] [$1000] Android - Error attempting to download an attachment #25491

Closed
1 of 6 tasks
izarutskaya opened this issue Aug 18, 2023 · 50 comments
Closed
1 of 6 tasks
Assignees
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor

Comments

@izarutskaya
Copy link

izarutskaya commented Aug 18, 2023

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. Open a random report and send an attachment (image, video, etc).
  2. If it's an image, click on the image, and when the image opens in full view, click on the download button. If it's a video or a different type of attachment, directly click the download button.
  3. Observe the error, and the attachment doesn't download.

Expected Result:

The attachment downloads successfully to the device without an error.

Actual Result:

An error appears, and the attachment does not get downloaded to device.

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android / native
  • Android / Chrome
  • iOS / native
  • iOS / Safari
  • MacOS / Chrome / Safari
  • MacOS / Desktop

Version Number: v1.3.55-4

Reproducible in staging?: Y

Reproducible in production?: Y

If this was caught during regression testing, add the test name, ID and link from TestRail:

Email or phone of affected tester (no customers):

Logs: https://stackoverflow.com/c/expensify/questions/4856

Notes/Photos/Videos: Any additional supporting documentation

recording_20230808_175024.mp4
Screen.Recording.20230818.173007.New.Expensify.mp4

Expensify/Expensify Issue URL:

Issue reported by: @NajiNazzal

Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1691506774751679

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01ea72aefb3af1826d
  • Upwork Job ID: 1692654340381872128
  • Last Price Increase: 2023-08-18
  • Automatic offers:
    • dukenv0307 | Contributor | 26261011
@izarutskaya izarutskaya added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Aug 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Aug 18, 2023

Triggered auto assignment to @garrettmknight (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot
Copy link

melvin-bot bot commented Aug 18, 2023

Bug0 Triage Checklist (Main S/O)

  • This "bug" occurs on a supported platform (ensure Platforms in OP are ✅)
  • This bug is not a duplicate report (check E/App issues and #expensify-bugs)
    • If it is, comment with a link to the original report, close the issue and add any novel details to the original issue instead
  • This bug is reproducible using the reproduction steps in the OP. S/O
    • If the reproduction steps are clear and you're unable to reproduce the bug, check with the reporter and QA first, then close the issue.
    • If the reproduction steps aren't clear and you determine the correct steps, please update the OP.
  • This issue is filled out as thoroughly and clearly as possible
    • Pay special attention to the title, results, platforms where the bug occurs, and if the bug happens on staging/production.
  • I have reviewed and subscribed to the linked Slack conversation to ensure Slack/Github stay in sync

@garrettmknight
Copy link
Contributor

Confirmed in browserstack

@garrettmknight garrettmknight added the External Added to denote the issue can be worked on by a contributor label Aug 18, 2023
@melvin-bot melvin-bot bot changed the title Android - Error attempting to download an attachment [$1000] Android - Error attempting to download an attachment Aug 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Aug 18, 2023

Job added to Upwork: https://www.upwork.com/jobs/~01ea72aefb3af1826d

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Aug 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Aug 18, 2023

Current assignee @garrettmknight is eligible for the External assigner, not assigning anyone new.

@melvin-bot
Copy link

melvin-bot bot commented Aug 18, 2023

Triggered auto assignment to Contributor-plus team member for initial proposal review - @burczu (External)

@rayane-djouah
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

Our application, designed to save files to the "Downloads/Expensify" directory, is experiencing challenges on Android 11+ devices. Specifically, the application struggles to fetch and store the intended files in the Downloads/Expensify directory.

What is the root cause of that problem?

The introduction of Scoped Storage in Android 11 is the primary factor behind this challenge. This feature:

  • Enforces stricter access controls to shared storage areas.
  • Prioritizes user privacy by restricting applications from having broad access to the file system.
  • Mandates applications to use certain APIs, such as MediaStore, for specific storage operations, particularly when accessing shared storage areas like the Downloads directory.

In our existing implementation, we use the RNFetchBlob library to download the file from the attachement URL and save it to the specified path, here:

// Fetching the attachment
fetchedAttachment = RNFetchBlob.config({
fileCache: true,
path: `${path}/${attachmentName}`,
addAndroidDownloads: {
useDownloadManager: true,
notification: false,
path: `${path}/Expensify/${attachmentName}`,
},
}).fetch('GET', url);

when we set a path and enable addAndroidDownloads with useDownloadManager: true, the RNFetchBlob library attempts to employ the Android Download Manager to fetch and directly store the file in the Downloads directory. However, from Android 11 onwards, designating a custom path for the Download Manager especially paths outside of the app's specific directory will result in failures, all thanks to Scoped Storage restrictions.

What changes do you think we should make in order to solve the problem?

Adapt to the Scoped Storage Model by Modifying RNFetchBlob Configuration:
Exclude the custom path instructions and the addAndroidDownloads configurations from our RNFetchBlob configuration by removing this lines:

path: `${path}/${attachmentName}`,
addAndroidDownloads: {
useDownloadManager: true,
notification: false,
path: `${path}/Expensify/${attachmentName}`,
},

As a result, the library will inherently fetch and store the file within the application's specific directory, ensuring alignment with Scoped Storage guidelines.

We have already an Integration with the MediaStore API in the rest of the code:
After the file is fetched within the application's directory, we use RNFetchBlob.MediaCollection.copyToMediaStore to save the file in the Downloads directory.

return RNFetchBlob.MediaCollection.copyToMediaStore(
{
name: attachmentName,
parentFolder: 'Expensify',
mimeType: null,
},
'Download',
attachmentPath,
);

This technique collaborates effectively with the Android MediaStore API, granting the application the capability to transfer the file to the Downloads shared directory, without contravening Scoped Storage policies.

Result:

Download.File.mp4

What alternative solutions did you explore? (Optional)

N/A

@rayane-djouah
Copy link
Contributor

@burczu please review my proposal

@dukenv0307
Copy link
Contributor

dukenv0307 commented Aug 21, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

An error appears, and the attachment does not get downloaded to device.

What is the root cause of that problem?

In here, we're appending DateUtils.getDBTime() to the attachment name to make it unique. So the attachment name will look like
rn_image_picker_lib_temp_aa2c7e8d-e497-43e6-8d3b-1b3d047457b7-2023-08-21 06:28:08.305.jpg

It contains colon :, which is an illegal character in file name, so Android wasn't able to save it.

What changes do you think we should make in order to solve the problem?

We need to remove the illegal characters like : before trying to download the attachment.

Replacing : by empty string will work for this issue, but there're more illegal characters, we should use a regex to remove them as well.

What alternative solutions did you explore? (Optional)

We can escape the illegal characters, but it will lead to not-good-looking file name.

Another way is, instead of using DateUtils.getDBTime() to get the unique time to append to the attachment name, we can use other safer time formats like timestamp or YYYY-MM-DD HHmmss instead. Or use other ways of enforcing uniqueness (uuid, ...) that doesn't have special characters.

@melvin-bot melvin-bot bot added the Overdue label Aug 21, 2023
@burczu
Copy link
Contributor

burczu commented Aug 21, 2023

not overdue - I'm reviewing proposals right now

@melvin-bot melvin-bot bot removed the Overdue label Aug 21, 2023
@burczu
Copy link
Contributor

burczu commented Aug 21, 2023

I wasn't able to reproduce this issue - I've tried Pixel 5 with Android 11 and Pixel 6 Pro with Android 12 (both emulators). On what devices did you test it? @izarutskaya maybe you can help me with it?

@rayane-djouah
Copy link
Contributor

@burczu

For devices with Android 11 and above, I've reproduced this on Pixel 3a with Android API 34, Android 14.

Screenshot 2023-08-21 112921

For devices with Android below 11, where the bug is not occurring, I've tested on Pixel 3a with Android API 34, Android 8.

Screenshot 2023-08-21 113526

@izarutskaya
Copy link
Author

@burczu I used Samsung M 52/ Android 13 and it's still reproducible for me

Screen.Recording.20230821.133615.New.Expensify.mp4

@AmjedNazzal
Copy link
Contributor

@burczu I think it happens on samsung phones which you can't emulate on andriod studio

@burczu
Copy link
Contributor

burczu commented Aug 21, 2023

Thanks @izarutskaya and @rayane-djouah - I'll give your configs a try.

@rayane-djouah
Copy link
Contributor

I think it happens on samsung phones which you can't emulate on andriod studio

I don't think so, I'm able to reproduce on Pixel 3a emulator on android studio

@AmjedNazzal
Copy link
Contributor

I think it happens on samsung phones which you can't emulate on andriod studio

I don't think so, I'm able to reproduce on Pixel 3a emulator on android studio

You're using android 14, is that stable? because as far as I know that hasn't been officially released yet and it's a beta release at the moment. I've tested on pixel 6 android 13 and wasn't able to reproduce.

@burczu
Copy link
Contributor

burczu commented Aug 21, 2023

Ok, I was able to reproduce it with Pixel 3a with Android API 34, Android 14 as @rayane-djouah suggested. I'll try with Android 13 too, to dispel @AmjedNazzal doubts. Thanks

@burczu
Copy link
Contributor

burczu commented Aug 21, 2023

Hmm... @AmjedNazzal was right here - it is not reproducible on Pixel 3a with Android 13 🤔 I've also tried on Galaxy Nexus with Android 13 which is available in Android Studio and it is also not reproducible...

@garrettmknight I've wrote that you've confirmed it on BrowserStack - on what device and with which Android?

@AmjedNazzal
Copy link
Contributor

@burczu I don't think the galaxy nexus would be helpful here. If I'm to guess, the issue is probably occurring because of samsung one ui since it's involved in apps interactions with the native system. We should probably run and test dev on physical samsung phones.

@garrettmknight
Copy link
Contributor

Tested on a Galaxy S22 v12.0 in browserstack.
Screenshot 2023-08-21 at 11 31 33 AM

@melvin-bot
Copy link

melvin-bot bot commented Aug 30, 2023

The solution for this issue has been 🚀 deployed to production 🚀 in version 1.3.58-5 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2023-09-06. 🎊

After the hold period is over and BZ checklist items are completed, please complete any of the applicable payments for this issue, and check them off once done.

  • External issue reporter
  • Contributor that fixed the issue
  • Contributor+ that helped on the issue and/or PR

For reference, here are some details about the assignees on this issue:

As a reminder, here are the bonuses/penalties that should be applied for any External issue:

  • Merged PR within 3 business days of assignment - 50% bonus
  • Merged PR more than 9 business days after assignment - 50% penalty

@melvin-bot
Copy link

melvin-bot bot commented Aug 30, 2023

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@burczu] The PR that introduced the bug has been identified. Link to the PR:
  • [@burczu] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
  • [@burczu] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
  • [@burczu] Determine if we should create a regression test for this bug.
  • [@burczu] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
  • [@garrettmknight] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:

@burczu
Copy link
Contributor

burczu commented Aug 31, 2023

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@burczu] The PR that introduced the bug has been identified. Link to the PR: n/a
  • [@burczu] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment: n/a
  • [@burczu] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion: n/a
  • [@burczu] Determine if we should create a regression test for this bug.
  • [@burczu] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
  • [@garrettmknight] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:

@aimane-chnaif
Copy link
Contributor

Hmm, I'd say this regression came from #23531 but they couldn't have caught this earlier in PR review since this happens only on android specific devices.

@melvin-bot melvin-bot bot added Daily KSv2 Overdue and removed Weekly KSv2 labels Sep 5, 2023
@garrettmknight
Copy link
Contributor

Payment tomorrow!

@melvin-bot melvin-bot bot removed the Overdue label Sep 5, 2023
@garrettmknight
Copy link
Contributor

garrettmknight commented Sep 7, 2023

Summary of payments:

  • urgency bonus? Yes
  • Reporter: @NajiNazzal - $250 paid via Upwork
  • Contributor: @dukenv0307 - $1500 paid via Upwork
  • Contributor+: N/A

Upwork Job: https://www.upwork.com/jobs/~01ea72aefb3af1826d

@garrettmknight
Copy link
Contributor

@NajiNazzal I just sent you an offer in Upwork. Accept and I'll pay this out.

@melvin-bot
Copy link

melvin-bot bot commented Sep 11, 2023

@garrettmknight, @robertjchen, @burczu, @dukenv0307 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

@melvin-bot melvin-bot bot added the Overdue label Sep 11, 2023
@melvin-bot
Copy link

melvin-bot bot commented Sep 11, 2023

@garrettmknight, @robertjchen, @burczu, @dukenv0307 Whoops! This issue is 2 days overdue. Let's get this updated quick!

@garrettmknight
Copy link
Contributor

Paid and done!

@aimane-chnaif
Copy link
Contributor

@garrettmknight I was C+ on this issue

@garrettmknight
Copy link
Contributor

Ah, missed that here. Let me spin up a contract, but in the future, make sure you're assigned to the issue!

@garrettmknight
Copy link
Contributor

@melvin-bot melvin-bot bot added the Overdue label Sep 13, 2023
@robertjchen
Copy link
Contributor

Looks like it was accepted, closing this out!

@melvin-bot melvin-bot bot removed the Overdue label Sep 14, 2023
@aimane-chnaif
Copy link
Contributor

@garrettmknight I haven't received payment yet. Can you please check?

@aimane-chnaif
Copy link
Contributor

@garrettmknight I haven't received payment yet. Can you please check?

bump ^

@aimane-chnaif
Copy link
Contributor

aimane-chnaif commented Nov 2, 2023

@robertjchen can you please reopen the issue? I haven't received payment yet

Edit: Thanks @garrettmknight. Just received payment. No need to re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor
Projects
None yet
Development

No branches or pull requests

9 participants