Skip to content

Add presence detection using the firebase realtime database websocket #507

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

raindrift
Copy link

Fixes #506

With this PR, whether a user has their browser window open and connected is reflected in the UI, and the connected property on their participant record. It allows the experimenter to know if the participant is still present, which is important for experiments that involve participants interacting with one another.

This works by using the firebase rtdb's existing presence functionality, and a cloud function that mirrors the user's state into firestore.

  • Tests pass
  • Appropriate changes to documentation are included in the PR

@raindrift
Copy link
Author

FYI, I have tested this on the emulator, where it works well and is quite fast. However, if we find in production that it's too slow to respond when someone connects, we should be able to add an endpoint so the client can update the status proactively, rather than waiting for the trigger to fire.

"$experimentId": {
"$publicId": {
".read": "true",
".write": "true"
Copy link

Choose a reason for hiding this comment

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

Does this make the db open to the public?

Copy link
Author

Choose a reason for hiding this comment

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

It makes this key open to the public, but you can only access records for known IDs. Since research participants are anonymous (from an auth perspective) there is no other way.

However, I notice that I misnamed that ID. So lemme go fix that...

Copy link

@pdarche pdarche left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@@ -36,6 +36,7 @@ export interface ParticipantProfile extends ParticipantProfileBase {
currentStatus: ParticipantStatus;
timestamps: ProgressTimestamps;
anonymousProfiles: Record<string, AnonymousProfileMetadata>;
connected: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this field is added, can we make the ParticipantProfile backwards compatible on the frontend (i.e., if reading in previously stored experiments) by adjusting the snapshot listeners in ParticipantService, ExperimentManager, and CohortService (if field is meant to be included in ParticipantProfile, not just ParticipantProfileExtended - see other comment)? You'll notice we did this already with agentConfig field.

Copy link
Author

Choose a reason for hiding this comment

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

Oh good point! I wasn't considering backward compatibility at all.

@@ -36,6 +36,7 @@ export interface ParticipantProfile extends ParticipantProfileBase {
currentStatus: ParticipantStatus;
timestamps: ProgressTimestamps;
anonymousProfiles: Record<string, AnonymousProfileMetadata>;
connected: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this new field intentionally under ParticipantProfile (all participants have access to other participants' connected status), or should it be under ParticipantProfileExtended (only experimenters or the current participant has access to the participant's status)? My understanding is that it might be more appropriate under the latter?

Copy link
Author

Choose a reason for hiding this comment

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

It wasn't intentionally there, but I think it needs to be there. With this change, isActiveParticipant depends on the connected property, and it's used in a bunch of the participant views.

@raindrift
Copy link
Author

Ok, updated to make the connected property optional. Also now makes sense for agent participants. Previously it would show them as always offline. I guess this is technically true in a way, but not useful. Now it will show them as always online instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When a participant disconnects, I don't have any way to know
3 participants