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

Features/readtimestamps: Read timestamps from FireStore; Pause Uploading to FireStore and Hide/Unhide Timestamps #39

Merged
merged 22 commits into from
Mar 11, 2024

Conversation

carolinentran
Copy link
Contributor

@carolinentran carolinentran commented Mar 11, 2024

Read timestamps from FireStore; Pause Uploading to FireStore and Hide/Unhide Timestamps

♻️ Current situation & Problem

Relevant issues: UI trigger for changing a flag field to true for data that the user wants redacted

Currently, the DeleteDataView that allows users to review and “hide” their data uses a hard-coded array of timestamps, so it does not access nor read in timestamps for the specified data type from Firestore. Second, users cannot “unhide” their data after choosing to hide it. Third, DeleteDataView currently does not support hiding data via a custom date range.

To address the first issue, we created a function to fetch the10 most recent timestamps from Firestore. In DeleteDataView, we display this list under the “Hide by Timestamp” section.

Second, we changed all functionality from “deleting” data to “hiding” data to better represent what is actually happening to user data on the backend. We modified addDeleteFlag to switchHideFlag so that users can “unhide” their data and have this status change reflected in Firestore’s hideFlag field. We also modified the UI so that an open/crossed-out eye is shown signaling which timestamps are hidden/unhidden.

Third, we created the “Hide by Custom Range” section in DeleteDataView so users can select a date range to delete data via the date pickers. We created the function fetchCustomRangeTimeStamps() to get a list of all timestamps in the specified date range. Since we want all data in this range to be hidden regardless of the previous hideFlag values, we modified switcHed Flag to take in a third parameter (read below).

Lastly, we made modifications to communicate the enable/disable status of sample category uploads between the DeleteDataView, ManageDataView, and PrivacyModule. Saving the toggle value allowed users to pause or unpause uploads of that data type to firestor (see PrismaStandard+HealthKit).

⚙️ Release Notes

PrismaStandard+Healthkit:

  • Before uploading a HealthKit datapoint to Firestore, check the toggle status in the identifierInfo dictionary in PrivacyModule . If the toggle is disabled, the HealthKit datapoint should not be uploaded to Firestore.
  • switchHideFlag(): Modified switchHideFlag logic so users can hide/unhide data to update hideFlag in Firestore accordingly. Also modified to take in an extra parameter “alwaysHide” bool. If the user hides by custom range, “alwaysHide” is set to true, meaning the hideFlags are always set to true regardless of original value. Otherwise, the hideFlag is toggled (false set to true and true set to false).
  • fetchTop10RecentTimeStamps(): Create function which fetches the top 10 most recent timestamps for a given data type (e.g, step count) and returns the populated array.
  • fetchCustomRangeTimeStamps(): Create function which fetches all timestamps in given date range by start date and end date pickers in “hide by custom range” and returns the populated array.

PrivacyModule:

  • identifierInfo dictionary: maps the identifier string (e.g. “stepcount”, “heartrate”) to information needed for the UI and the hideFlag functionality (e.g. enabledBool status).
  • sortedSampleIdentifiers list: using the sampleTypes list in PrismaDelegate, send a list of the string identifiers for each type with prefixes trimmed – ensures that only the sample types allowed by the Prisma app will be displayed to the user in ManageDataView. Refactoring this allowed us to create a publisher that signaled views to refresh upon changes to the identifierInfo dictionary.
  • identifierInfoSubject Combine publisher that sent signals to views subscribed – views will refresh upon changes to the sample type toggles (e.g. disabling the upload of step count data points)
  • updateAndSignalOnChange() function that updates the identifierInfo dictionary with the new toggle boolean and sends out a signal to subscribing views.

ManageDataView:

  • Updated to use identifierInfo dictionary and sampleTypes list
  • Subscribed to the identifierInfoSubject Combine publisher; upon receiving a signal from the publisher, the view refreshes its “Disabled”/”Enabled” status

DeleteDataView:

  • In “Hide by Custom Range” section, created date pickers for start and end dates so users can select a date range to hide all data in between dates. Pass the start and end date into fetchCustomRangeTimeStamps() to fetch all timestamps in this range, then call switchHideFlag() with alwaysHide = true to set hideFlags to true.
  • In “Hide by Timestamps” section, display the timestamp array populated by fetchTop10RecentTimeStamps(). Upon tapping the eye icon, hidden status switches as reflected in the change in icon and graying/un-graying out. Then, call switchHiddenInBackend to hide timestamp in Firestore.
  • Updated to use identifierInfo dictionary
  • When a new value is set for the toggle, it calls updateAndSignalOnChange() to update the dictionary and send out signals to subscribing views.

Next Steps:

Write unit tests for implemented features.

📚 Documentation

N/A

✅ Testing

  • In featureFlags.swift, switch set useFirebaseEmulator to false.
  • Replace the appropriate GoogleService-Info.plist
  • Erase all content and settings from the simulator device.
  • Run the app and login using personal account and password (corresponding to account on FireStore)

Roles

Evelyn:

  • Create switchHideFlag() function in PrismaStandard+Healthkit to switch hideFlag from false to true and vice versa in Firestore to reflect hide/unhide timestamp changes by user in DeleteDataView.
  • Create fetchTop10RecentTimeStamps() function which fetches the top 10 most recent timestamps for a given data type (e.g, step count), stores the timestamps into an array, and returns the array (which will be called in DeleteDataView).
  • Create fetchCustomRangeTimeStamps() function which fetches all timestamps in given date range by date picker in “Hide by custom range”
  • Modify switchHideFlag() function to take in an additional parameter alwaysHide bool. alwaysHide is set to true if the user hides by custom range, otherwise it’s set to false.
  • Create UI for hide by custom range using date pickers (calendar view) in DeleteDataView to allow users to hide data in a specified date range
  • Create UI for displaying 10 recent timestamps for the data category item, showing each timestamp’s Firestore hideFlag status via an open/crossed-out eye.
  • Create switchHiddenInBackend() function inside DeleteDataView that calls switchHideFlag in PrismaStandard+HealthKit to switch hideFlag status

Caroline:

  • Refactored data communication between the PrivacyModule, ManageDataView, and DeleteDataView to reference and use only the HKSampleTypes from the PrismaDelegate by creating sortedSampleIdentifiers list.
    SortedSampleIdentifiers list alphabetized the sample types to display for the user. This list kept all UI information within the dictionary in PrivacyModule and passed on as few parameters as possible. The refactoring of this was necessary to ensure that the app’s HKSampleTypes were the only ones shown to the user (allowed the app to be flexible and modular to future app-wide modifications). The new structure also allowed for the publisher addition mentioned in the next point.
  • Created the Combine publisher in the PrivacyModule to signal all subscribing views to refresh their pages with new identifierInfo dictionary values.
  • Debugging: An issue we ran into during this PR was how different devices and different types of samples had different effectiveDateTime/effectivePeriod fields. With Matt’s help, the timestamps were intended to be sorted by “time.datetime.start” but in swift, the “datetime.start” field was not recognizable so we resorted to using the “issued” time.

Dhruv:

  • writeToFirestore(): took Evelyn and Caroline’s code for writing to firestore and put it into its own function for sake of modularity
  • add(): included functionality in the PrismaStandard to not write to Firestore if the HKSample has an off toggle
  • PrivacyModule(): refactored a majority of the PrivacyModule class to include initialization with a list of HKSampleTypes, and used this to map each corresponding identifier to a bool for representation in ManageDataView and DeleteDataView

📝 Code of Conduct & Contributing Guidelines

By submitting creating this pull request, you agree to follow our Code of Conduct and Contributing Guidelines:

evelyn-hur and others added 21 commits March 6, 2024 16:22
…tore

In DeleteDataView, change deleting timestamps to hiding. In PrismaStandard+HealthKit, modify addDeleteFlag to switchDeleteFlag so hiding and unhiding timestamp from UI can switch deleteFlag field to true and false and vice versa in Firestore.
In DeleteDataView, remove "edit" button so hidden icon always shows (no need for edit button anymore)
In DeleteDataView, added data type description section and "hide by custom range" date pickers for start and end date. Fixed UI spacing/padding issues by reformatting form and section views.
… + delete ToggleTestView

Minor Changes: Rename all functions and variables from delete to hide. Also deleted toggleTestView which is no longer needed.
Previously, the ManageDataView had a list created from a hardcoded dictionary (which would have shown more/fewer sample types than what was defined in the PrismaDelegate). Modified all other views dependent on PrivacyModule.

Restructured the communication between PrivacyModule and ManageDataView. Originally, ManageDataView was passed a list of structs with all the icon, identifier, UI string, and toggle status elements. This is repetitive with the dictionary that is already in PrivacyModule so I just passed the vector of sorted identifier strings instead (and ManageDataView and DeleteDataView accessed necessary information accordingly)
In PrismaStandard+Healthkit, add new function fetchTop10RecentTimeStamps to read in timestamps to display top 10 most recent timestamps in DeleteDataView. For now, sorting by "effectiveDateTime" field but need to generalize to all data types by sorting by timestamp document name.
Small bug when merging with Caroline's changes
Fixed bug for fetchTop10RecentTimeStamps by sorting document IDs in ascending order for now. Currently, can't sort in descending order so may have to eventually sort by fields instead of document IDs.
…anch

there are some errors that were fixed and pushed with code in main, have to update branch by merging main into branch

Expected to fail all checks for now
Created a publisher that monitors the dictionary in PrivacyModule. Since the DeleteDataView and ManageDataView are dependent on the dictionary content, if there are any changes to the dictionary, the publisher will signal the ManageDataView to refresh.
previously, updateAndSignalOnChange() only sent a signal to all subscriber views. It made more sense for DeleteDataView to send the new toggle value to updateAndSignalOnChange() which updates the dictionary and sends the signal.

Added descriptions for each category. Missing descriptions for: distancewalkingrunning, workout
With Matt's updates to the timeIndex dictionary fields, we updated our fetching top ten timestamps to sort by descending order by the "time.datetime.start" field
…nt timestamps

There is a bug that I was not able to fix after debugging with Matt and Bryant. We decided to resort to using the "issued" timestamp instead for fetching the 10 most recent timestamps.
In PrismaStandard+Healthkit, created function fetchCustomRangeTimeStamps to get all timestamps within specified time range from date pickers. Also modified switchHideFlag to take in the alwaysHide bool (set to true if hiding by custom range, otherwise false). In DeleteDataView, modified hideByCustomRangeSection accordingly.
Copy link

codecov bot commented Mar 11, 2024

Codecov Report

Attention: Patch coverage is 36.93931% with 239 lines in your changes are missing coverage. Please review.

Project coverage is 36.20%. Comparing base (c3e1ceb) to head (ad275fd).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #39      +/-   ##
==========================================
+ Coverage   34.66%   36.20%   +1.55%     
==========================================
  Files          44       43       -1     
  Lines        1694     1942     +248     
==========================================
+ Hits          587      703     +116     
- Misses       1107     1239     +132     
Files Coverage Δ
Prisma/PushNotifications/PushNotifications.swift 8.34% <0.00%> (ø)
Prisma/Standard/PrismaStandard+TimeIndex.swift 0.00% <0.00%> (ø)
Prisma/PrivacyControls/PrivacyModule.swift 94.52% <95.81%> (-1.20%) ⬇️
Prisma/PrivacyControls/ManageDataView.swift 27.28% <12.50%> (+27.28%) ⬆️
Prisma/PrivacyControls/DeleteDataView.swift 0.00% <0.00%> (ø)
Prisma/Standard/PrismaStandard+HealthKit.swift 4.00% <0.00%> (-4.42%) ⬇️

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c3e1ceb...ad275fd. Read the comment docs.

Copy link
Contributor

@bryant-jimenez bryant-jimenez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work !! The views look really good. Just set the useFirebaseEmulator flag back to true and its good to go.

@bryant-jimenez bryant-jimenez added the enhancement New feature or request label Mar 11, 2024
@carolinentran carolinentran merged commit 257bbcd into main Mar 11, 2024
7 checks passed
@carolinentran carolinentran deleted the features/readtimestamps branch March 11, 2024 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
4 participants