Skip to end of metadata
Go to start of metadata


User story

(info) See  YD-33 - Getting issue details... STATUS

  • Jimmy, a Yona youth, happens to surf the web on a saturday afternoon. He heads for a well-known poker site and starts playing.
  • Jimmy's internet actions are analyzed by the Yona first-step request classifier, the requests to the poker site are classified as red and forwarded to the second-step analyser.
  • Since Jimmy did setup a Yona profile with a danger zone for gambling (among other dangers), the analyser detects a conflict and raises an event.
  • One of the subscribers to the event is the notifier, which prepares notifications for both Jimmy and his buddy Clark. As both youths are registered with their mobile phone, the notifier can send push notifications to them. The notification text for Jimmy reminds him of his danger zone. The notification to Clark is confidential to such extent that it states 'One of you buddies has entered a danger zone. Please check and act responsible'.

The selected cloud service to implement this is Firebase, Google's mobile platform. It supports both Android and iOS.

Note that for direct messages sent to the user we do not have the devices of the user available, as the devices are stored in the anonymized part of the user. Therefore notifications cannot be used to announce direct messages. An SMS may be used instead, as direct messages are sent only very few.


Use Firebase for Yona

Setting up Firebase for Yona is easy:

Questions

Question: Do we use notifications to display the messages in the system tray, or just send a data message that the app can process? (See concepts for the difference.)

Answer: We use data messages so that the Yona app can open itself or show a notification itself when a message is delivered and display the message. An advantage is that we do not have to send sensitive information over Firebase. Another advantage is that the Yona app can support e.g. expanding the message, grouping multiple of them or replying directly.

Question: How should the app display that a message has arrived? Should it show a popup? Should it highlight the messages icon if there are unread messages? Should it open itself?

Answer: TBD UI design!

How does it work

The brief story is:

  • The Yona app connects to Firebase. A device-specific Instance ID will be generated by Firebase and sent to the Yona app with an onTokenRefresh event.
  • The Yona app should send this Instance ID to the Yona server 
    • When installing the Yona app the first time, it should be connected after confirming the mobile number. It can then be sent as a PUT on the device. 
    • When registering a new device, POST it in step 10 in Flow - Add another device.
    • When Firebase refreshes the token (now and then), PUT it on the device again.
  • The Yona server will save this Instance ID in the (unencrypted) device properties (on DeviceAnonymized).
  • The Yona server can then at any time send notifications to a device/all devices of the user using their device Instance IDs.
  • The Yona app can act upon the notification
    • When the app is active and a Push notification is received, refresh the messages
    • When the app is activated by the user tapping the Push notification, refresh the messages and act as if the specific message was tapped. For this to work, the Push notification must include the message URL.

A bit extended for safety:

  • The Yona server should show on the current device whether the Instance ID is already known at the server. If it isn't, the Yona app knows it should connect to Firebase and/or resend the Instance ID to the server.

Requirements for Yona server

  • Support PUTting and POSTing the Instance ID as a device property  YD-549 - Getting issue details... STATUS
  • The devices of the user are returned in the user profile, with the currently acting device marked with requestingDevice = true. That device should also return the instance ID known at the server.  YD-549 - Getting issue details... STATUS
  • Send notifications to Firebase using the user device Instance ID when a message is sent to the user. The notifications will be sent to all devices of the user having a known Instance ID.  YD-550 - Getting issue details... STATUS
    • To be decided if this is required for the app implementation: Include the message URL in the notification key-value properties  YD-604 - Getting issue details... STATUS

Requirements of Yona app

  • Register on Firebase after the mobile number has been confirmed
  • Listen to Firebase onTokenRefresh event, call getToken() and send the Instance ID to the Yona server 
    • When installing the Yona app the first time, it should be connected after confirming the mobile number. It can then be sent through a PUT on the device. 
    • When registering a new device, POST it in step 10 in Flow - Add another device.
    • When Firebase refreshes the token (now and then), PUT it on the device again.
  • The devices of the user are returned in the user profile, with the currently acting device marked with requestingDevice = true. If the instance ID on that device differs from the ID retrieved through getToken(), the app should PUT the current instance ID on the device.
  • Implement receive of the message
    • See documentation for Android and for iOS
    • When the app is foregrounded,
      • Refresh the messages
    • When the app is backgrounded, no need to do something, as the app does not cache messages
    • When the app is backgrounded and launched by a tap of the notification,
      • Act as if the specific message was tapped using the message URL included in the Push notification key-value set (if any)

Detect legacy situation of multiple devices

Because people are using multiple devices with Yona and the app does not yet support registering multiple devices (the server did not have the device notion before), we will have a legacy situation for multiple devices that are registered under the same device entity without the Yona server knowing it. The Instance ID introduced by Push notifications gives the opportunity to detect and fix this legacy situation. Algorithm:

  • When the user is using multiple devices with Yona under the same device ID, it will occur that device 1 will send its Instance ID to the server and when device 2 is opened, it will find that the server has associated an Instance ID with it while it has no Instance ID yet.
  • The app can detect if the server already knows an Instance ID but the app itself does not yet have an Instance ID.
  • In that case, the app should create a new device and register itself with that new device (do all the steps of Flow - Add another device, but this time on the same device):
    1. Generate "new device request password" (an OTP of 6 mixed-case alphanumeric characters)
    2. PUT this on the yona:newDeviceRequest link of the User, while passing the Yona-Password header as usual
    3. Perform a GET on /newDeviceRequests/{mobileNumber} to see whether a new device request exists. In this case, it will exist. The response includes a yona:registerDevice link, needed for step next step.
    4. Perform a POST on the URL returned in the yona:registerDevice link retrieved in the previous step (this will normally be /users/{userID}/devices/) with the device information (name, operating system, etc.), while passing the generated password of step 1 in the Yona-NewDeviceRequestPassword header. Note the constraints for name, operating system, etc. described in the Swagger spec.
    5. The server now returns the user profile. The app should store the self-link of that profile as the user URL. It'll be slightly different than before, as it now includes the new device ID in the query string. The Yona password will be unchanged.
    6. Perform a DELETE on the yona:newDeviceRequest link of the User , thus removing the encrypted copy of the Yona password from the server.
    7. From here, the app should perform the regular Firebase registration as described under How does it work.
  • No labels

1 Comment

  1. That's right. The stored user entity should be replaced with what's received from the server.