Meteor : How to implement a private message in a chat room? - chat

Actually I'm more interested in the techniques to use to achieve this task more than really building a chat system (which is an excellent concrete example). I see 2 parts:
The client needs to get registered somewhere, and we then need a unique ID per client.
The server should be able to send something to the client only from another client.
For the first part, I do not know how to get this unique id. Possibly using the new meteor auth kit ?
For the second part, I thought about building a per-client collection in which one and only one client will have access to, but it sounds heavy and In my opinion not really in the Meteor best practice. I then thought of adding a "from" and to "field" to a Message (see the regular chat example). This would do it but I'm wondering about the no privacy on them. Would a custom publish returning a filtered find do it or it is risky too i.e. would other client get the items too ? Something like:
Meteor.publish("message", function (clientID) {
return Messages.find({"dest":clientID }, {});
});

The latest Meteor todos example uses the new auth system to identify private todo entries. I would imagine that you could use the same mechanism to identify the originator and recipient of a private message in a chat like system.
Of course the filtering of which messages someone sees would need to be filtered on the server side to maintain privacy.

Related

Firebase cloud functions chess game Swift

I am making a chess app which has a Firebase backend, i am using cloud firestore and cloud functions. basically i am using node 8 to avoid billing issues on cloud functions, i can call and trigger, but i can't wrap my head about how to make an action happen on another device instead of on my own.
After authenticating and logging in, the user gets into a lobby which is a tableViewController and there are shown only the users that are currently logged in.
What i want to achieve is by tapping on a certain row the user that got the tap on it gets an alert shown for him which states whether he accepts the challenge or he declines it. Based on that i proceed to the game or do something else.
The question is though how to make this alert trigger on the other user's device?
Also i've seen some posts that it can be done with snapshotListener on a document, but again i run into the problem of understanding how to trigger the alert on another device. If you've got some other good ideas please share!
Thank you for any feedback!
I think snapshot listeners are really the only way to go. You could use other Firebase services but those aren’t the right tools for the job. Consider creating a collection, maybe call it requests:
[requests]
<userId-userId> (recipientUserId-initiatorUserId)
initiator: string
recipient: string
date: date
Each user has a snapshot listener that listens to this collection where their own userId is equal to recipient. You can add a date field to sort the list by most recent, for example. When a user wants to challenge another user, all they need to do is create a document in this collection:
<userId-userId> (recipientUserId-initiatorUserId)
initiator: myUserId
recipient: theirUserId
date: now
And the recipient's client will instantly see this document.
You could include dressing data in this document, like the initiator's display name or a path to their avatar. But this data may be stale by the time it's rendered so the alternative is to fetch the dressing data from the database using the userId. You could also auto-gen the document ID but if you configure it (like this), it can make operations like deleting simpler. You could also configure the userIds to be alphanumerical so only one request can exist between two users; but if they requested each other at the same time, one would overwrite the other and you'd have to handle that potential edge case. There are lots of things to consider but this is the starting point.

Implementing visitor counter in flutter for web

I'm trying to implement a visitor-counter on a website built entirely with flutter-web and I'm trying to accomplish this with nothing but plain dart code and some packages from pub.dev.
But the problem which has been bugging me is that I need to find a way to uniquely identify users based on their browsers or their devices so that I don't end up incrementing the counter for the same person again and again upon a revisit.
So far what I've thought is that I could use firestore for keeping track of the total number of visitors and display the same on the webpage upon startup and use some caching package like dcache or localstorage (like described here) to keep track of users who are re-visiting the same webpage.
Is there any better approach to this problem? Any help would be appreciated 😁
(ps: I have no prior web dev experience)
Since you talk about users, I immediately think of using Firebase Authentication.
There are two ways you could use that here:
With anonymous authentication, you could create a unique ID for each user without requiring them to enter credentials.
If you want to be able to identify the same user on different browsers/devices, they will have to sign in with one of the supported providers (email/password, phone number, email link, facebook, google, etc).
No matter which one you choose, each user will now have a unique ID (called UID in Firebase terms), which you can use to identify them in the database. For example, you could create a document for each user in the database with their UID as the ID of that document. That way you're guaranteed that each user will have no more than a single document.
You'll still need to count the documents, for which I recommend checking out the distributed counter extension.
Also consider if you want to use the Firebase Realtime Database instead of Firestore here, as it might give you a simpler pricing model, and has a built-in presence system. You'd still use Firebase Authentication as before, but just swap the database.
There is a short way instead if you just want to capture number of visitors on your webapp.
I created a collection called "Visits" in firestore and generated auto id inside which I added a field called "count". That's it!
Now you just have to call this method in your first screen's init method :
updateCounter() async {
final cRef = FirebaseFirestore.instance.collection('VISITS');
await cRef
.doc("mS9fCXjvkpREt8LvanSb") //Paste the id which was generated automatically
.set({"count": FieldValue.increment(1)}, SetOptions(merge: true));
}

Yii2 notification system implementation

I am trying to implement simple notification system in Yii2.
I have a list of Records populated in ListView.
I would like to allow users to vote for this records. Only once per Record.
Also the Author of each record must be notified (smth like new incoming emails) about who voted for his Record.
What is the easiest way to implement this in Yii2?
Thanks for an advice!
With php only you can't do that, you need to have js at some point.
Solution One could be, from user B side you keep asking the server after certain time (using ajax), if anything(event) happened. If it does return the result with that ajax and update the page.
But then again this is not a very good practice.
If you really want a Real Time update, you might want to use socket.io. Then again using php socket is a bad idea.
So here comes the Solution Two: yii2 + redis + nodejs + socket
redis will do the communication between yii2 and nodejs. The idea is, if anything (event or update) happens yii2 will publish a event with associate data to redis channel and nodejs which is listening to that channel will catch that event and send the data (or update) to client using socket.
Here is a real time chat application tutorial using yii2+redis+nodejs+socket.

MongoDB Concurrency Issue

I have a scenario for my app which is similar to sending friend request in Facebook.
When user A sends friend request to user B, internally a new friend request document is created. At a later time when user B also wants to send friend request to A, system would find out that a friend request document existed and so they should be friend of each other, no new friend request document would be created.
I'm trying to figure out the case when user A and user B both simultaneously sends friend request to each other which will then create 2 friend request documents and leading to undetermined behaviour...
Thanks for your suggestions.. Really appreciated!
Edit:
A few had suggested to use a request queue to solve this; however,
I'm confused about using queue because i thought it would make my rest api endpoint process requests sequentially. Wouldn't I lose all the benefit of multi-threading by using queue? I can't help but imagine how bad it would be if my service has millions of requests queued and waiting to be executed one by one just due to this issue. Has anyone seen something along similar problems seen in production?
I had similar situation with my client which has concurrent writes in the database, What I have implemented is a Queue service.
Create a request in the queue rather than writing in the database, a separate reader will
read one message from the queue at a time and check if it is valid to write it to
database, write only if there is no previous request.
You can implement your own queue or you can use service like AWS-SQS, rabbitmq, MSMQ etc.
// Specific to your case
In mongodb write operations on a single document are atomic.
mongodb has a feature of unique index.
Hence if you insert the document with an _id(or any other unique index) with person names A and B by creating unique index for both (such as "A_B" by lexicographically sorting the names) before doing insertion. You will inherently be able to insert only one instance of that document.
// General
What essentially we would like to have are transactions but since mongodb doesn't support such, as of now. There are a few tricks to achieve this:
2 phase commits :
https://docs.mongodb.org/v3.0/tutorial/perform-two-phase-commits/
Using an external source to maintain a flag, for example using memcache which supports insertion in transactional manner/Compare and Swap.
Here if you use system calls method in frontend then you should fire one request to frontend from Database when some user like, I send you request then within a sec database send you one system call and your frontend code immediate correct the button text like
"Add a friend" to "incoming request"
or else.
if you are only setting up database then just make a system call which send it to UI when friend request arrives or as you say Document created, the further process will be handled by UI Developer.
Thank you.
if you don't like the answer then I m apologize for that but don't downvote me because I M new in Stack Overflow Community.

scala lift comet

So basically I need a system like this:
We got users
Users have friends
Now the users if they come on the website they can post an "activity" just like twitter, they type in what they are doing, and all their friends get with a realtime update.
I have looked at lift for a week or three, and I digged into the chat server example, how ever as I said how can I make an comet actor for "activities" that where posted by friends?
I see two general approachs:
Do it the same way like the chat example: Just use one "Chat"server that holds all activities and every user is registred with. If a new activity is posted, every user would be informed and has to check if the activity was posted by one if its friends (via match/PartialFunction probably). If yes it display it, otherwise discard it.
Use one "Chat"server per user and register only the user's friends with this server. Note: I don't know if you need one comet listener per server for each of the user you are following in this case or if a comet listener can listen to several servers. If you need one listener per server, you will have to combine all activities you're listening to before displaying theese.
Approach 1 is closer to the ChatServer example but I would suggest to follow approach 2 since there's less communication in it so it should scale better. Also using different servers should improve scalability since you're able to do partitioning based on that. Of course you will have to some more management than using only one singleton "Chat"server.