Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 6547

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 27, 20242024-11-27T07:33:08+00:00 2024-11-27T07:33:08+00:00

You have unread messages

  • 60k

Imagine creating a profile on this job searching site that promises to connect you to industry insiders. A recruiter sees it and messages you with a dream opportunity. But, you never see the message because you signed up to this site for fun and haven't logged back in to check your messages for weeks. That was Ninjobu, at least up until a few days ago.

In the last post, I wrote a bit about how I set up the chat system so recruiters could communicate with candidates. One significant omission was new message notifications. Since we have a web app here, it's unlikely people stay active on the platform for long, the way you might do on social media or IM. And, arguably, user communication is a crucial part of asynchronous job searching. It made sense for the next feature to be a way to let users know when someone contacts them.

My goal was to write a simple solution that would notify users when they have new unread messages while not being too naggy. The resulting structure ended up straightforward, implemented with just two Firebase functions.

chat_format.png

As mentioned in the previous post, our database consists of chat documents that store the last message timestamp and when each chat participant last viewed that message. With this information, we can easily decide which users we should notify.

First, I added a new Firebase function that triggers on writes for each chat document. The onWrite trigger executes for the creation, updates, and deletions of documents. I ignore the deletion case, but I know the last message timestamp will have updated during the creation and update events.

on_write_func.png

When a chat is updated, it will have a lastMessageTime timestamp and an array lastSeenTime with two entries: one timestamp for each of the two chat participants, representing when they last saw the chat. If any of the lastSeenTime timestamps are older than the message, we record the chat id in a document misc/chats_to_notify for later. Firebase's FieldValue.arrayUnion utility lets us atomically add unique entries to an array.

With the above function running every time a chat document is updated, we will end up with a list of chat ids in our misc/chats_to_notify document. The next step is to go through these chats and send emails to the participants, as required. We do this with a second function that we schedule at a set interval.

Being tightly integrated with GCP, Firebase offers many features from Google Cloud wrapped in simple-to-use interfaces. One example is scheduling functions that run at predefined intervals, using Google Cloud Pub/Sub and Scheduler behind the scenes. The function that handles our email notifications is a bit chunkier, so let's split it into smaller parts.

notification_func_0.png

I set up the function to run once every two hours, quickly done with the App Engine cron.yaml syntax.

notification_func_1.png

Start by retrieving the misc/chats_to_notify document where we have the ids for our updated chats, and early out if the document is invalid or the list of chats is empty.

notification_func_2.png

Once we have our chats, I chose to process only up to 100 of them on each invocation. Firebase functions have a running time limit of 60 seconds, and I don't want the function to time out and not send any emails if the list of updated chats is too long. However, my choice is a bit premature and speculative. The 100 chats limit was chosen arbitrarily, and Firebase allows the function timeout to be configured to up to 9 minutes. I'm also unsure how the function itself will scale with a significantly larger array of chat ids. I will likely have to tweak this once I have more data. But for now, processing 100 chats every 2 hours seems reasonable based on the website's current activity.

While looping over each chat, we add its id to the processed array and later use it to remove the entry from the misc/chats_to_notify document. Next, we retrieve the chat document data and validate the required fields. We need lastMessageTime to exist and the members array to contain the two chat participants' UIDs. We then save each member's UID if their lastSeenTime is older than the lastMessageTime. This check is important because, between the time the chat id was recorded in the misc/chats_to_notify document and the time this function runs, each member of the chat may have already seen the last message. We don't want to send an email notification for a read message. Our onWrite function for the chat document only adds chat ids to the notification list and doesn't remove them.

A thing to keep in mind here is, if we have 100 chats where the participants have both seen the messages, this function will process those chat entries and not send any emails until the following invocation 2 hours later. I'm not entirely happy with this, but I consider this part of the code temporary until I have more data on how many emails one run of the function can process.

notification_func_3.png

We now have a list of UIDs for users that need to receive a notification email. For each UID, we get the user's email from the Firebase Auth module and create a personalization entry. Personalizations are a Sendgrid feature that lets us send the same email to multiple recipients with a single API call. It also ensures that each recipient will only see their email address in the to field and avoids catastrophic invasion of privacy.

notification_func_4.png

Finally, we remove all the chat ids we have processed from the misc/chats_to_notify document to avoid sending multiple emails to the same folks. The FieldValue.arrayRemove feature allows us to do this quickly with a single call.

Speaking of the array with chat ids, it may be worth noting that at some point, this may become a bottleneck. Firestore document sizes have a limit of 1 MiB. If we assume the auto-generated chat ids continue to be 20 bytes each like they are at the moment, we have room for a bit over 50,000 entries in the array before we blow the size limit. Additionally, Firebase has a soft limit of one write per second to the same document that they don't recommend you go over to avoid contention errors. It's a soft limit in the sense that it shouldn't cause issues in short bursts, but something to keep in mind. If there's loads of chat activity on the site, the misc/chats_to_notify document will be hammered and potentially go over the one write per second limit. Once we hit these problems, however, congratulations are in order, most likely.

Thank you for reading this far. If you are a software engineer open to new opportunities but not actively looking for work, try out Ninjobu! Create a profile, let recruiters know what job and salary you'd like, and who knows what might happen.

Until next time.

firebasewebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.