Twilio Video/Chat - javascript

I am working on a reactjs - Twilio video/chat application. Its a requirement to include the name of the person as a tag on top of the video.
However when I look at the json response with the participatory information - it only lists an identity id -- is there a way of pushing a name into the service, or doing a lookup on Twilio for the name of the person?
So where you have
identity: "17003",
personName: "Bob Pip"
https://www.npmjs.com/package/twilio-video
I am able to get the sid and the identity.
During video connect tried to pump in a custom value for this localparticipant to push it into the service.
var connectOptions = {
name: roomName,
personName: 'Collin Baker',
logLevel: 'debug'
}
Video.connect(data.token, connectOptions)
but it doesn't come out.
"Hey, so, the short answer is "no" you can't do that through the Video SDK itself."
"However, I would recommend checking out Twilio Sync (https://www.twilio.com/docs/api/sync ). Sync is an API that let's you sync data across devices. So, you could create a sync object that contains the id that you use with the Video SDK paired with the user's visible name."
"They wouldn't link up directly, but if you keep your identities consistent (i.e. User Id from your db) and then keep the visible user name also in sync in the Sync object, then you can share that object between calling parties and display the names. You might, for example, also keep one sync document per video room."
https://www.twilio.com/docs/api/sync/sync-sdk-download
https://www.twilio.com/sync
https://www.twilio.com/docs/api/sync/quickstart-js
https://www.twilio.com/docs/api/sync/identity-and-access-tokens
"Ah, Sync is in beta, so you need to install the alpha version of the npm library. Slightly confusing I appreciate, it's something like twilio#3.4.0-alpha1"

Related

Firebase Auth Built-in identity

I am building a web platform to connect learners with tutors using Firebase Auth and Firestore. I am storing the learners' user info in a Firestore collection, and the tutor's info in another. I am building a function that can detect if a client is a learner or a tutor upon login.
One solution I was thinking is to query in which collection the user is found using UID. Although, this is a potential solution. But it sounds like it requires a lot of transaction, and may have a long run time if collections get big. Is there something else I can do for that? I am wondering if I can use authentication to build an embedded identity to each user to differentiate between "Tutor" and "Learner"? So each time the user logs in, we know the identity immediately?
I know that in the decoded authentication token, there is info such as this:
{ iss: 'https://securetoken.google.com/xxxx',
aud: 'xxxx',
auth_time: 1569886929,
user_id: 'aB03',
sub: 'aB03',
iat: 1570582588,
exp: 1570586188,
email: 'aa#gmail.com',
email_verified: false,
firebase:
{ identities: { email: [Array] }, sign_in_provider: 'password' },
uid: 'aa3' }
Can I leverage one of these to build what I want?
Really appreciate your time and help.
Since you mention "collection", I assume you're looking to use Firestore. In that case: the size of the collection has no effect on the query performance. No matter if there are 1,000 user documents in the collection, 1,000,000 or even 1,000,000,000, the time it takes to query for a single user document will always be the same.
Aside from that you can also store the user's type in the ID token (which is what you've shown in your question). This is known as a "custom claim", since you're adding a custom property for your app to the information. You'll want to do this from a trusted environment (your development machine, a server you control, or Cloud Functions), as I'd assume users should not be able to change their own role. See the documentation on controlling access with custom claims for more information on this.

Storing sensitive data in Vuex

To summarize, we are using Vue on the front-end and Hapi JS on the back-end. The front end uses MSAL.js to authenticate users and then passes an access token to the back-end. The access token is decoded with hapi-auth-jwt2 and the validate() function returns { isValid: true, credentials : { ps_ref: 12345, md_userid: asfasgsg#5874.com }}. This object is then passed to the handler function of a route which extracts authentication groups/user roles (i.e.Auids) from our DB and user data and returns that.
Imagine that the user object looks like this:
{
Auids: (4) ["user", "webadmin", "accounts"]
md_clock: 5678
md_picture: "./images/"
ps_fname1: "Test Name"
ps_surname: "Test Surname"
psname: "Test Name Test Surname"
psref: 125125
}
Now, we would like to store this object in Vuex, however, we are concerned that it will be visible to anybody who has installed the Vue Devtools in their browser or anybody who executes something like rootElementOfApp.__vue__.$store
Our questions are:
How easy it is for somebody to access the Vuex in production?
If it is easy enough to access Vuex by the public, is Vuex the best way to store this object? If we go for Vuex should we encode the user object or at least the Auids in it ?
Everything you store in the js/html/cookies is not save on it's own. But it is all related how you will manage it. Basically you can store almost everything in the front end, as long it isn't sensitive data that's usable for ethical hacking. Things like addresses, contract numbers, bank accounts etc.
Data like userIds (as long only used for programmatic reasons) or a user roles can be stored in the front end. But if you do it right you always have every client side validation also in your back-end application.
In terms of dev tools of vue they are only available in development mode not production. But a good hacker doesn't mind.

Firebase >> User Favorites List

I need a little assistance with my app. I'm not asking for a handout, just some guidance as to where to begin. The basic idea is for logged in users to be able to favorite videos, and to have them persist when logged in.
My app uses the YouTube API (Playlist Items) to display videos from my public playlists within my app. I'm using firebase auth to register and login users, but I have yet to implement the RTD. This is where I need some assistance in structuring my data & organizing my app.
I don't want favorite lists created for every user by default, nor do I want to store false values and have to loop through them. I'd only like to set a favorites list if the user requests to do so, and the values are true. I'm open to suggestions regarding structuring my data, but I was thinking something simple like this:
"favorites": {
"John Doe": {
"video1ID": true,
"video2ID": true,
}
}
Videos are contained within cards using a .each function from within the API response. Included in these cards are "favorite" toggle switches that I'd like a user to be able to toggle and add a favorite video to their list.
YouTube provides Video ID's from within their JSON response. I was thinking that assigning a boolean to that video ID would get the job done, but I have no idea where to begin.
Something like:
function writeFavoritesList (name, videoID, toggleValue) {
firebase.database().ref('favorites/' + userId).set({
name: displayName,
videoID: videoID,
toggleValue: true
});
}
I'm very much a newb to anything outside of WordPress, so I hope I'm on the right track. Any help appreciated. Thanks! :)
Looks great. If this were another database, you could consider storing the video IDs in an array, but this being the firebase RealTime Database, you're much better off with objects, which you've already got.
You could modify your structure slightly to take advantage of RTDs push() key generation if you ever intend on sorting your favourite videos. To do so, instead of making the key the videoID and the value the boolean status, you could generate a key using firebase's push() key generation and make the value the videoID. "The unique key generated by push() are ordered by the current time, so the resulting list of items will be chronologically sorted. The keys are also designed to be unguessable (they contain 72 random bits of entropy)."
"favorites": {
"uid1": {
"uniqueKey1": videoID1,
"uniqueKey2": videoID2,
}
}
To generate a push() key, use: const key = firebase.database().ref().push().key.
More info: https://firebase.google.com/docs/reference/js/firebase.database.Reference#push
Saw your Guru post. I think the best way for you to learn is to delve deep into the documentation and figure this out for yourself. If you're truly committed to learning this stuff you'd be doing yourself a disservice to have someone else write the code for you.
I'd start with the GCP(Google Cloud Platform) cloud firestore docs and read through the Concepts section in its entirety:
https://cloud.google.com/firestore/docs/concepts
The firebase site mirrors parts of the GCP documenation, but also covers client implementations:
https://firebase.google.com/docs/firestore/
To get the most out of these docs use the nav sidebar on the left to drill down into all the various Cloud Firestore topics. They go into how to structure your database and provide sample code for you to analyse and play with.
You'll see the terms Documents and Collections thrown around a lot. A Document is somewhat equivalent to a JSON Object. A Collection is a list of documents; similar to an array of JSON objects. But here's where things get interesting; Documents can reference Collections (aka Subcollections):
So I would structure your database as follows:
Create a Users collection
Whenever a new user signs into your app, create a user document and add it to the Users collection.
The first time a user selects a favorite video create a Favorites collection and add it to the user document; then add favorite documents to the Favorites collection for this user
There is a Javascript/Web client (you've seem to already have it loaded from what I've seen in the repo link you provided on Guru). Here's the reference documentation for it:
https://firebase.google.com/docs/reference/js/firebase.firestore
The classes, methods and properties defined in those reference docs are what you'll be calling from within your jquery code blocks.
Good luck and stick with it.

Conditional publish events

Introduction
I'm building a private messaging system using sails, but this question can apply to pretty much anything. I'll be using the messaging system as an example to make the question more clear. As a bit of background info, I'm working with the latest sails 0.10 RC.
The problem
Sails allows you to use redis for sessions and pubsub, which allows you to scale over multiple servers. This is all very neat and works brilliantly, but it leaves me with the question of how to publish events to specific connected sockets (clients).
Sometimes you wish to only publish events to participants, as is the case with a private messaging system. Only the author and recipient should be notified of new messages in the thread. How would you accomplish this? I know you can subscribe a client to a specific model instance, notifying the client of changes in said model; I also know it's possible to subscribe a client to a model, notifying them of newly created (saved) model instances. It's the latter, the create verb that's causing me a bit of trouble. I don't want everyone that's using the messaging system to receive updates for new messages in threads they're not in. This would be a privacy issue.
TL;DR
How can I filter which clients receive the create verb event based on the value of a property (author and recipient) on the model in question? Is there any other way to make sure only these clients receive updates for the model?
You have a few options here, but all of them involve not really using the default publishCreate method, which will just blast out the created message to everyone who was subscribed to it via .watch().
The first option is to use associations to link your Message model to the users who should know about it, and then listen for the publishAdd message instead of publishCreate. For example, if there's an association between a Message instance and the User instances who represent the sender and recipient, then the default publishCreate logic will also trigger a publishAdd for the related users, indicating that a new Message has been added to their messages (or whatever you name it) collection.
The second option is to override the default publishCreate for Message, to have it send only to the correct users. For example, if only the recipient should be notified, then in api/models/Message.js you could do:
attributes: {...},
publishCreate: function (values, req, options) {
User.publish(values.recipient, {
verb: "created",
data: values,
id: values.id
}, req);
}
As a slight alternative, you can place your custom code in the model's afterPublishCreate method instead, which the default publishCreate will then call. This has the benefit of maintaining the default code that handles calling publishAdd for associated models; the trick would be just to make sure that no one was subscribed to the model classroom via .watch(), so that the default publishCreate doesn't send out created messages to users who shouldn't see them.

Adding a user to PFRelation using Parse Cloud Code

I am using Parse.com with my iPhone app.
I ran into a problem earlier where I was trying to add the currently logged in user to another user's PFRelation key/column called "friendsRelation" which is basically the friends list.
The only problem, is that you are not allowed to save changes to any other users besides the one that is currently logged in.
I then learned, that there is a workaround you can use, using the "master key" with Parse Cloud Code.
I ended up adding the code here to my Parse Cloud Code: https://stackoverflow.com/a/18651564/3344977
This works great and I can successfully test this and add an NSString to a string column/key in the Parse database.
However, I do not know how to modify the Parse Cloud Code to let me add a user to another user's PFRelation column/key.
I have been trying everything for the past 2 hours with the above Parse Cloud Code I linked to and could not get anything to work, and then I realized that my problem is with the actual cloud code, not with how I'm trying to use it in xcode, because like I said I can get it to successfully add an NSString object for testing purposes.
My problem is that I do not know javascript and don't understand the syntax, so I don't know how to change the Cloud Code which is written in javascript.
I need to edit the Parse Cloud Code that I linked to above, which I will also paste below at the end of this question, so that I can add the currently logged in PFUser object to another user's PFRelation key/column.
The code that I would use to do this in objective-c would be:
[friendsRelation addObject:user];
So I am pretty sure it is the same as just adding an object to an array, but like I said I don't know how to modify the Parse Cloud Code because it's in javascript.
Here is the Parse Cloud Code:
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId,
newColText = request.params.newColText;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.set('new_col', newColText);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
And then here is how I would use it in xcode using objective-c:
[PFCloud callFunction:#"editUser" withParameters:#{
#"userId": #"someuseridhere",
#"newColText": #"new text!"
}];
Now it just needs to be modified for adding the current PFUser to another user's PFRelation column/key, which I am pretty sure is technically just adding an object to an array.
This should be fairly simple for someone familiar with javascript, so I really appreciate the help.
Thank you.
I would recommend that you rethink your data model, and extract the followings out of the user table. When you plan a data model, especially for a NoSQL database, you should think about your queries first and plan your structure around that. This is especially true for mobile applications, as server connections are costly and often introduces latency issues if your app performs lots of connections.
Storing followings in the user class makes it easy to find who a person is following. But how would you solve the task of finding all users who follow YOU? You would have to check all users if you are in their followings relation. That would not be an efficient query, and it does not scale well.
When planning a social application, you should build for scalabilty. I don't know what kind of social app you are building, but imagine if the app went ballistic and became a rapidly growing success. If you didn't build for scalability, it would quickly fall apart, and you stood the chance of losing everything because the app suddenly became sluggish and therefore unusable (people have almost zero tolerance for waiting on mobile apps).
Forget all previous prioities about consistency and normalization, and design for scalability.
For storing followings and followers, use a separate "table" (Parse class) for each of those two. For each user, store an array of all usernames (or their objectId) they follow. Do the same for followers. This means that when YOU choose to follow someone, TWO tables need to be updated: you add the other user's username to the array of who you follow (in the followings table), and you also add YOUR username to the array of the other user's followers table.
Using this method, getting a list of followers and followings is extremely fast.
Have a look at this example implementation of Twitter for the Cassandra NoSQL database:
https://github.com/twissandra/twissandra

Categories

Resources