Is there a way to detect changes in the Healthkit data when the phone is locked? - healthkit

As you may know, when the iPhone is locked, the HealthKit data gets encrypted, but data may still be added to the HealthStore by the phone (eg. When you are walking, step count will be added even if the phone is locked)
I tried using a HKObserverQuery to check for updates in the HealthStore for the number of steps. But as expected, it failed when the phone the phone is locked.
Is there any alternate way to detect changes in the StepCount data in the HealthStore (By using only the HealthKit functionalities. Not a combination of CoreMotion and HealthKit etc.)

Unfortunately, no. There is no way to access HealthKit store data while the phone is locked as stated in the documentation and confirmed in the comments of this SO post.

Related

How to handle offline aggregation using Firestore?

I have been scouring the internet for days on a solution to this problem.
That is, how to handle aggregation when there is no network connection? I have a task management app that looks to aggregate meta data about user tasks. For example, the task can contain tags that can be aggregated to be shown in a dashboard to the user on a daily basis. This would be easy if the user is always online, so I could use transaction or cloud function to aggregate, but when the user is offline, the aggregation will appear to be incorrect, until the user restores their network connection.
Aggregation queries are explained here:
https://firebase.google.com/docs/firestore/solutions/aggregation
Which states a limitation:
Offline support - Client-side transactions will fail when the user's
device is offline, which means you need to handle this case in your
app and retry at the appropriate time.
However, there has yet to be any example or documentation on how to 'handle this case'. How would I go about addressing this problem?
Some thoughts:
I could cache the item if a transaction fails. This item will be aggregated on top of the stored aggregation. However, going down this line would mean that I can't take advantage of the Firestore's "offline mode", because I'm using my own cache on every write while offline anyway.
I could aggregate on demand. That is, never store the aggregation. This is going to be very heavy on read depending on how many tasks a user has. Furthermore, if the aggregation will need to be shared as insights to other users, this option will not work because other users do not have access to the tasks.
I'm at a loss and any help would be appreciated, thanks!
After a lot of research and trial and error I found a solution that can address this problem gracefully.
FieldValue.increment to the rescue.
What FieldValue.increment does is bypass the use of transaction while respecting the default Firestore's offline cache behaviour. It requires the use of set or update on the field directly. The drawback is the inability to use the 'withConverter' on the collection for type safety. I'm willing to live with the drawback considering how useful FieldValue.increment is.
I've done multiple tests and can confirm that the values can be incremented/decremented multiple times locally while offline. This offline value is reflected in a get or snapshot call to the cache. When the network connection is restored, the values are updated on the server.
The value itself is not stored on the cache, it simply stores the "difference" in the FieldValue sentinel for when it is time to update it on the server.
This method only works with incrementing and decrementing values. Storing averages will not be possible using this method. That is because the true total number of items is not known at the time of its calculation when offline.
Instead, the total number of items are stored along side the total value. The average is then calculated when and as needed. In this way the average will always be accurate from a local perspective when offline, and it will also be accurate when online when the total value and count has been synced.

How to know if a message is seen or not

We are displaying list of messages on user message feed. Messages are stored in a feed collection, where its organized by users. We want want track if user has seen the message or not
feed/{user_id}/
{message_id1: {seen:0,score:0.2}}
{message_id2: {seen:0,score:0.2}}
{message_id3: {seen:1,score:0.2}}
At present we are thinking to update "seen" boolean for a given message if user has seen it. Are there more efficient ways to do this in firebase (e.g. firebase native analytics). Not sure if doing so many writes back efficient
There are two common ways to track what messages a user has seen:
Keep a flag for each message that the user has seen.
Keep the timestamp/key of the most recent message that the user has seen.
The letter is a lot easier to implement, but relies in the fact users typically read message in order: scrolling from their oldest unread message to the newest message. If that is not the case for you, there's not really a better option than tracking the status for each message (and in a multi-user chat room, for each user too).
Also see:
How to structure NoSQL messages to get unreads by 1 query? (long explanation with examples of the same use-case, but then for Firebase's Realtime Database)

DynamoDB or RDS?

I keep going back and forth about choosing DynamoDB or RDS for my project. I understand they are 2 completely different kinds of DB systems, but I am not sure which one would be a better fit for my app. My app alerts users of certain events that happen VERY infrequently.
For instance, an employee may trigger an alert saying that there is an active shooter in the building, so my app needs to get the cell phone numbers of everyone in the company from the database and then use those numbers to send text messages. I just discovered that DynamoDB has a limit of 100 items when retrieving stuff from the database, which is a problem for me because I may have to retrieve 200 or 300 or even more phone numbers as quickly as possible.
In addition to this, the database would not be queried regularly. It would be queried rarely when someone needs to update a user's profile information. of course, it would be queried for users' cell phone numbers in an emergency and I need this to return the results as fast as possible.
It kind of sounds like DynamoDB may be an overkill, but I am not 100 % sure. On the other hand, It seems a PERFECT fit since it can query stuff really quickly, but the limit of 100 items per request just kills me.
To me, there isn't a clear answer in terms of what database system to choose. Based on this use case, what is the best DB option?
You should use AWS pinpoint for that. Pinpoint has endpoints and segments.
The endpoint is email, number... One person in the company can have multiple endpoints.
The segment is a filtered list of endpoints. For example, you can filter endpoints by person title, or by company.
You create Campaign based on segments, so each person in selected segments get email or SMS or both...
Regarding your example, you can create a dynamo DB trigger which will create/update/delete pinpoint endpoints.
AWS approach is not to scan dynamo DB to send group emails or SMS. Instead of that, the approach is to create segment and then create campaigns.

Loading conversation messages in chat app with Firestore

When building a chat app with React Native and Redux, with Firestore for backend, what is the best way to load messages for a particular conversation?
I display 8 chat entries in the beginning, and when I click at one I will see the chat screen with 20 latest messages. Is it a good idea to implement real time listeners to each chat's (not all chats, just those that are displayed, because pagination is used) 20 latest messages from each one's messages collection and have them ready beforehand?
Or is it a better idea to load the messages when a particular chat's messages screen is being opened.
I understand that as user experience the first option is better because there is no latency in showing the first 20 messages for a chat, but doesn't it consume a lot of data that might never be necessary, because out of the 8 chats, the user might interact with only 2 or 3.
Is there any better way besides these two?
Thanks in advance!
If is a good idea or not, it's up to you to decide according to what kind of chat app you want to create. It's always a trade between the latency that you were talking about and the amount of data that you get and that might be or might not be seen by the user. Furthermore, if you say you have 8 chat rooms with 20 messages, it means that by default, when the user opens your chat app, Firestore will charge you with 8*20=160 read operations, even if the user enters a chat room or not and I think is not such a good idea. If you have a few users, there won't be a problem but if your app grows, you might think again about this. In Firestore, everything is about the number of reads and writes according to their pricing plan.
In my opinion, you should think of upgrading your UX by giving the app offline capabilities instead of loading unnecessary data all at one. You should fetch data for a concerned chat and make your app memorize the latest 10-20 messages and you can always sync your data. You might want to consider Realm or SQLite.
Also for better UX for the chats screen where the chats will be shown, you should consider making your chat-list node to accomodate last message and timestamp in each chat so that you wont have to nest the query for each chat item for just one screen rendering.

Can ASP.NET Session ID be the same on two machines at the same time?

I have an ASP.NET application that uses Session.SessionID to prevent multiple users viewing the same data at the same time.
I have a table that contains a set of images (stored in BLOB) that require processing. Only one user is supposed to be able to view the same image at the same time. To achieve this, as each record is retrieved by a user the record is updated with the Session.SessionID. This update occurs inside a ReaderWriterLock.
I have done a test to ensure the ReaderWriterLock is working correctly and can confirm that only one session can execute the code inside that block at once.
My current theory is that two different users are getting the same SessionID at the same time. A user of this application is allowed to view records they have locked or any unlocked images.
I have modified the application to display the SessionID in the footer of every page so that if the problem happens again I can check the SessionID value.
I've seen some articles online suggesting that SessionID is not unique and some saying that the SessionID is unique. I understand that SessionID is not unique forever but can the SessionID value be considered unique for active sessions?
This forum describes a similar problem
I have also read some suggestions that a Guid should be stored in the Session object and used as a unique ID instead of the Session ID.
Thanks for the responses so far. Here is a clarification based on the answers so far:
"Locked forever" - we prevent this by a lock timeout of 5 minutes. Before a user locks an image, while inside the ReaderWriterLock, we do a "cleanup" of old locks (which unlocks images locked for more than 5 minutes), a query to get the oldest unlocked image and an update statement to "lock" that image to the current session.
A possible cause of the problem would be if one user "locks" an image but then leaves the PC for a short break. If they did nothing for 5 minutes, that image on there screen would be unlocked and potentially opened by another user. I mentioned this scenario when the problem was reported and I was assured that the users had been working continuously.
"Different Window/Tab" - I haven't actually seen the error with my own eyes but the person who reported the problem has told me that it is two different PC's and two different usernames of the logged in user.
Hopefully now that I am displaying the Session ID on the page, next time it happens I will be able to say with certainty whether it is the same Session ID on two machines or if it is some other problem. This issue has never occurred during the testing phase so it appears to be a symptom of a larger number of concurrent users.
Thanks for the responses so far and I will update this question as more information comes to hand.
It seems that the user didn't give me the full story. Session ID is unique in our case as per the accepted answer. Two users were able to see the same image at the same time because user 1 was idle for the 5 minute "abandoned image" unlock process. The "abandoned image" timeout has been raised to match the session timeout to avoid this problem.
Session ID is unique per user as far as ASP.NET assigns them, though that is not a guarantee against malicious users (a user could manually copy the ID they've been assigned and give it to someone else).
What you are likely seeing here is multiple tabs or windows from the same user, as it is perfectly valid for a user to be making more then one request at a time.
To do what you want I would have to ask - how do you know when a user has stopped looking at an image, so you can unlock it. What if I view an image, and then just close my browser instead of going to another page/image, does it remain locked to my (lost forever) session id?
If you are using some kind of checkout scheme - the user must intentionally check out and check in an image, then you should perhaps be using a unique number for that checkout (new Guid), rather then the whole user.
Red flag here people.
Yes you can but it's absolutely essential that you can't or at the very least make it as difficult as possible to re-use them in the future.
This is dependent on how well your server side application is handling Session ID's and maintaining State. You should (actually MUST) think about limiting session_ID lifetime, how you look after authentication /authorisation state.
I saw in a critical trading platform at a top 10 investment bank whereby you could capture Session ID's on the fly (that contained authorised permissions) and re-use them (through a tool such as Paros from ParosProxy.org) to perform $multi million trades on someone else's behalf. In the current climate - is this an issue? ;-) Sorry - as much as I'd love to name & shame these clowns, I won't.
How likely is this scenario? Can you capture Session ID's on a Switched Network? Certainly within a local VLAN using the hacking tool CAIN and taking advantage of ARP poisioning you can.
In a poorly written Server Side application, you can also predict Session ID's. Check the tool WebScarab (which is in any Pen Testers armoury). This will detect the randomness of ID's. At the same bank with another critical application you could generate your own Session ID's to access & trade applications. Their focus was on low latency (which is business critical) rather than Security.
An intro can be found at Owasp.org
Noelie Dunne
This link says session ids are unique - http://support.microsoft.com/kb/899918
Session ids are unique in that only 1 session will ever have that id at any given time.
If this wasn't the case I think there would be a lot of people shouting very loudly about it.
The Session ID is almost certainly unique to the user. Failure modes where several users share a SessionID are very, very rare today. However, a user can do several things to create the effect you are seeing.
For instance the user can have several tabs open in her browser. Those tabs will all share the same Session ID. So if she switches back and forth between those browser tabs it might give the effect you are seeing.
Another issue is that users frequently doubleclick buttons and links. This means a processing request may get issued twice with the same Session ID. I would check for this possibility first.

Resources