Get pusherapp members count in channel without counting self - javascript

Pusherapp counts yourself when you subscribe to get a members count. Is there any way to not include yourself?
I have a preview view with a members in channel count. If I join the room in another tab I would like that number to go up.
The problem with getting the count, then minus one is that when you actually do join the number won't go up. It also counts other members who are looking at the preview and not where I would actually intentionally subscribe them. Any ideas?

There are 3 possible methods:
You can work out who you are in the members collection by comparing it to the members.me object. See: http://pusher.com/docs/client_api_guide/client_presence_channels#members_me
You can query Pusher's Web API to get a count of users. See:
http://pusher.com/docs/rest_api#method-get-users
Each user will have an ID so you can work out which one is the current user using that.
You could register a Presence WebHook so that your server is notified whenever a user joins or leaves a channel. In this scenario you may need to maintain your own count, but you can get the initial value using method 2, above.
There is no way right now to simply query the members and say "exclude me" as part of that query. So the only solution is to get the full collection (on the client or server) and implement some custom counting logic.

Related

How to write data into a specific location Firebase Web

I want to write data into a specific location in the database. Let's say, I have a couple of users in the database. Each of them has their own personal information, including their e-mails. I want to find the user based on the e-mail, that's to say by using his e-mail (but I don't know exactly whose e-mail it is, but whoever it is do something with that user's information). To be more visible, here is my database sample.
Now, while working on one of my javascript files, when the user let's say name1 changes his name, I update my object in javascript and want to replace the whole object under ID "-LEp2F2fSDUt94SRU0cx". To cut short, I want to write this updated object in the path ("Users/-LEp2F2fSDUt94SRU0cx") without doing it by hand and just "knowing" the e-mail. So the logic is "Go find the user with the e-mail "name1#yahoo.com" and replace the whole object with his new updated object". I tried to use orderByChild("Email").equalTo("name1#yahoo.com").set(updated_object), but this syntax does not work I guess. Hopefully I could explain myself.
The first part is the query, that is separate from the post to update. This part is the query to get the value:
ref.child('users').orderByChild("Email").equalTo("name1#yahoo.com")
To update, you need to do something like this once you have the user id from the query result:
ref.child('users').child(userId).child("Email").update(newValue);
firebase.database.Query
A Query sorts and filters the data at a Database location so only a
subset of the child data is included. This can be used to order a
collection of data by some attribute (for example, height of
dinosaurs) as well as to restrict a large list of items (for example,
chat messages) down to a number suitable for synchronizing to the
client. Queries are created by chaining together one or more of the
filter methods defined here.
// Find all dinosaurs whose height is exactly 25 meters.
var ref = firebase.database().ref("dinosaurs");
ref.orderByChild("height").equalTo(25).on("child_added", function(snapshot) {
console.log(snapshot.key);
});

firestore: arrays vs sub collection of documents performance

i would like to ask if there is a best practice for firestore, when one develops a chat app, and what is the best practice to store messages for chat-rooms.
The assumption here is that every chatroom has its own document.
I started using an array to store the messages from the users. The problem with that approach is that there is no way to add, a insert(append) a new entry everytime a new message is submitted to the chat room. One has to save a new copy of the array with the new message appended. This seems like something that would scale really bad, unless the chat history is split in sub-arrays etc..
In the official documents, they suggest a structure, where one should store the messages of a specific chatroom as separate documents in a sub collection of that chatroom. I wonder if this approach is the best, and what would be some drawbacks, or if there is another preferred way to do this.
I would generally go with the approach of "Every chat room has a subcollection of messages. And every new message is a separate document in this subcollection." This has several advantages: It's easy to add or edit individual messages, and you can perform a number of different queries (like "Grab the 20 most recent messages")
The biggest drawback, I suppose, is that if you find that new users are frequently going to be entering your chat and will want to see the entire chat history of the room up until they joined, that would result in a large number of database reads. Realistically, though, I don't know how often that would happen in real life, and you could mitigate this by using pagination to grab your historical chat in batches.
To add to what Todd said:
In arrays you cannot store Timestamps - a big downside for your case, as you'll want the time the message was sent.

Inappropriate Redis Database Design

I have a node.js API that is responsible for 3 things:
Registering a buyer
Getting a buyer with ID
Finding the matching buyer's offer based on some criteria
Details here
Since I'm new to Redis, I started the implementation like this:
JSON.stringify the buyer and store it with SET
Store all buyer's offers as ordered set (this is for the third endpoint, which requires the offer with the highest value) - this set contains string that represents the name of a hash
Then, that hash stores strings that represent the names of sets that have certain values and a location which the user will be redirected to after these conditions have been fulfilled (buyer1_devices, buyer1_hours, etc.)
Now, here is the problem:
I need to get GET /route working. As described on GitHub page that I have provided, I have 3 parameters: a timestamp, devices, and states. I have to browse through all the sets and get the appropriate location to redirect a user to. The location is stored in a hash, but I have to browse through all the sets. Since this is probably a bad implementation, where did it all go wrong and to go about implementing this?
Note that this is a redis problem, not a node one. I need instructions on how to go about implementing this in Redis, and then I will be ready to code it in Node.
Thank you in advance
The first rule of Redis: store the data just like you want to read it.
To answer the /route query you need "filteration" on two attributes of from the buyers' offers - state and device. There is more than one way to skin that cat, so here's one: use many Sorted Sets for the offers.
Each such offers Sorted Set key name could look like this: <device>:<state> (so the example offered in the git will be added to the key desktop:CA).
To query, use the route's arguments to compose your key's name, then proceed regularly to find the highest-scored offer and resolve the buyer's details in the Hash.
Now go get that job!

How to store user actions in MeteorJs using MongoDB?

I'm using Meteor JS for a project so inherently I'm using MongoDB. I'm storing a user's check in and out actions. I'm currently storing them as individual docs in the collection. Each action contains 3 fields; in or out, time of action and userid. Is the best way to go though? Should I just have one doc per members and then store each action in an array? Is there another way? I anticipate several hundred members, but hopefully several thousands of members in the future. Thanks.
From experience, I can say that storing records instead of arrays is a better choice in the long run.
As far as Meteor is concerned, its reactivity handles collection records, but not individual fields in arrays. In other words, if one element gets added to the checkins array of a user object, the entire user object needs to be synchronized with the clients. If you store records instead, only the newly added record will be sent by the publication.
As far as MongoDB is concerned, there is a document size limit of 16MB. Not sure how frequent your checkins and checkouts are, but if you store them in an array, you might run into that limitation at some point.
Records are also easier to access than arrays.
For more details, see MongoDB data modeling and Database modeling in Bulletproof Meteor.

Javascript How to scale Array, prevent errors from undefined

I am currently creating a quiz app in meteor. One of the key variables Im using is called currentQuestions which keeps track of the questionnumber of each quiz the user has taken. It is currently an array which updates (in a Meteor session) everytime the user clicks the next or back button on a particular quiz. for example:
currentQuestion = Session.get('currentQuestion') || [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
This works fine for a small amount of quizzes. What would you suggest however when I want to have a large amount of quizzes? Currently when I create more quizzes than I have previously defined in the currenQuestion Array the app crashes.
Possible solution I have thought of
(Ugly solutions) Create a for loop that fills up the currentQuestion array with a large amount of zero's at startup.
Insert a object into the mongoDB database that contains the currentquestion with the id of the quiz that's taken (so getting rid of the array entirely)
Hope you can help.
Option 2 is definitely the right one:
If you don't need to keep track of scores between sessions, you can just use a client-side-only database and store objects as you suggest and it will be only a couple of lines of new code for a much more flexible outcome.
This would then be very easy to convert into a persistent store as well: either add sign-in with Meteor's accounts package, add the current userId to each quiz object, and then only publish the quiz objects with the same userId as the logged-in user. Alternatively, you could even use the amplify package to store results between sessions in a given browser if you wanted to avoid user login entirely (you'd have to pull existing results out again on startup, but this is very easy).
The result would have all the reactivity of a Session variable built in, and would avoid the need to populate an array with an arbitrary and changing number of zeros - just check whether the a document with the given quiz Id is in the collection or not, and if not then create it.
You'll need to get rid of the array entirely. If you are going to keep track between sessions then you'll need to go with something like mongoDB. You could created something like a progress or completion model which can hold info about the quizzes they have taken and progress for each. Once you have that stores those by some userId related key.
Your dirty solution is not the worst since you'll know at start how many quizzes you'll have and can allocate the array then.

Categories