Firebase One on One Chat - javascript

I am trying to create a one to one chat on a global firebase chat. I was wondering how would I proceed to do it? What I am doing now is that I created another HTML file which is where the private chats would happen and I am searching by users id
with this piece of code.
oneOnone.addEventListener('click', function(e){
// Attach an asynchronous callback to read the data at our posts reference
ref.on("value", function (snapshot) {}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
ref.orderByChild("userId").on("child_added", function (snapshot) {
console.log(snapshot.val().userId);
console.log(searchId);
if(searchId.value === snapshot.val().userId){
window.location.href = 'privatemessage.html';
}
});
});
This then leads into the privatemessage.html file where all the chats should happen. The feeling I have been having is that my database might not right.
The database on firebase still registers people as it would in a Global chat, not a 1 on 1 chat. I am just completely confused on how to make sure the chat would be between only two people. If someone could recommend a guide, give a full fledged explanation on how 1v1 chat would work that would be appreciated. Yes I have look at the docs, it really does not explain how to do a 1v1 chat.
Edit
So I have changed up my database to this
So what I am leaning on is something like this for the one on one talk
var pmChat = database.ref('chat/' + userId);
Basically creating a new reference and then linking the userid but now, how I link the userid of the other user?

you can link current user id with the other userid like this:
database.ref('chat').child(currentUserId).child(otherUserId).child(message);
database.ref('chat').child(otherUserId).child(currentUserId).child(message);

Related

Getting Firebase Realtime Database Value By Child

I'm developing an application that has a chat page.
I'm using Firebase realtime database and my chat structure like this:
I'm getting new messages as below:
fireBuddyChats = firebase.database().ref('/buddychats');
this.fireBuddyChats.child(this.currentUserId)
.child(this.buddy.uid)
.orderByKey()
.limitToLast(topMsgCount)
.on('value', (snapshot) => {
this.buddyMessages = [];
let temp = snapshot.val();
for(var tempKey in temp) {
this.buddyMessages.push(temp[tempKey]);
}
this.events.publish('newmessage');
}
I'm listening 'newmessage' event to show new message in chat page.
The problem is: While i chatting somebody, if another friend sends any message, database trigger (I mentioned above) runs and chat page shows another friend's messages. I think it shouldn't be triggered because the "this.buddy.uid" is different. What i'm missing? Is there any suggestion?
Maybe to prevent this you can add a conditional statement above to check if the user (the current user is talking to) actually has the uid of "this.buddy.uid". So maybe for the code you could possibly include somewhere:
if (socket.uid == this.buddy.uid).then
This should prevent other users from joining/adding themselves onto the real-time database conversation as it is checking if the user constantly.
Hopefully this helps.

Using Accounts.FindUserByUsername to search for usernames in Users collection (Meteor)

Would really appreciate some help here. Been banging my head against the table for a couple hours now.
I’m trying to create a simple search function to search for usernames. My goal is to be able to search the usernames and eventually add the selected username to a “teams” collection.
I’ve tried easy-search but had no luck. I’m trying to user Accounts.FindUserByUsername now but I keep getting undefined. I have accounts-password installed, btw.
This is my code:
Server side:
Meteor.methods({
findUser: function (username) {
const user = Accounts.findUserByUsername(username)
return user
}
})
Client side:
Template.search.helpers(function() {
Meteor.call('findUser', 'username', findUserCallback)
})
function findUserCallback(error, username) {
console.log(username)
}
Template.search.events({
'submit .search'(event) {
event.preventDefault()
Meteor.call('findUser', 'username', findUserCallback)
}
})
I know I’m doing something very wrong but I can’t figure out what. I haven’t found much help online.
Thank you so much – I really appreciate it!
Welcome to Stack Overflow Julia.
The Meteor users collection is special, because it's used for authentication, and access to other users is not advisable in the UI, because of the security risks.
It is usual to have another collection called 'players' or 'members' - the advantage of this is that you can store additional information, and you can easily publish/subscribe to these collections and manipulate them without the need to be writing Meteor methods to do your work.
In the new collection you can store the _id of the user, so you can always reference the user record (ie for the username) if you need to.

Firebase push() method shuffle the list data

Have created a chat application and we use firebase for realtime communication.
Sometimes i noticed that push() method shuffle the list data. We can see in the below image :
If we see in above image i am just trying to communicate with someone i said hello in reply user said hey, again i said i need some help then user said That's what I'm here for. What can I assist you with? in the reply but if we see in the image users reply is appearing first.
It happens intermittently that's why i didn't figure out this problem. So please someone help me out what shall i doing wrong.
var pushMessageToFB = function(){
var chatMsgRef = db.child("chatMessages").child("gr1").child("ch_usr1_usr2");
var message = {
type: "chat",
content: data.messageText,
timestamp: Date.now(),
by: user.id
};
chatMsgRef.push(message, function(err){
if (err){
console.log('error occurred while pushing message to fb : err ' + JSON.stringify(err));
}
});};
var loadChatMessages = function(){
var chatMsgRef = db.child('chatMessages').child("gr1").child("ch_usr1_usr2");
$scope.chatMessages = chatMsgRef.orderByKey().limitToLast(50);
};
Don't use Date for remote data. It will be slightly offset on every machine. Use ServerValue.TIMESTAMP which Firebase will convert to the server's Unix epoch time when the data is written. This ensures consistency of order across clients.
You didn't provide any code for how you're reading or displaying the chat messages, but since you're trying to show them in chronological order I assume your query uses orderBy("timestamp"). If you use ServerValue.TIMESTAMP when you write the message it will be guaranteed to sort in the order that it was written to the database.

Can you list users in Meteor without a login system?

For example, if I did a chatroom where all you ahve to do is enter a username (so you don't log in), can I still somehow list out all the people in that chatroom? How can I do this?
Instead of using the normal Meteor.users collection, it would probably be easiest to create your own collection for such simple authentication.
If you wanted to make it really simple (most likely, as long as you didn't care if 2 people have the same name), just store the name as a property of a chat room message document.
Edit - answer to comment:
To detect when a user disconnects, you can add an event handler in your publish function like this:
Meteor.publish('some_collection', function(){
var connectionId = this.connection ? this.connection.id : 'server';
this._session.socket.on("close", Meteor.bindEnvironment(function(){
// deal with connectionId closing
}));
});
You can do that.
Simply publish all users and every coming client should subscribe.
server:
Meteor.publish('allUsers', function(){
return Meteor.users.find({},{fields:{profile:1}});
})
client :
Meteor.startup(function(){
Meteor.subscribe('allUsers');
})
Template.listOfUsers.users = function(){
return Meteor.users.find();
}
This is very basic example, which should be adjusted to your needs.

How to handle user information using firebase simple login for facebook

I am building a webpage using AngularJS and Firebase. I want to use facebook login to connect information on the webpage with the user. Firebase has a version of simple login which I guess is supposed to simplify the login process.
My problem is that I want to access information about the logged in user in a lot of places on my webpage but I can't find a good way to do it.
This is how I started out:
var userInfo = null;
var ref = new Firebase('https://<yourfirebase>.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(ref, function(error, user) {
if(error)
alert("You are not logged in");
else if(user)
{
//store userinfo in variable
userInfo = user;
}
else
//user logged out
});
//do something with userInfo
alert(userInfo.name);
My first thought was to run this at the top of my page and then use the info about the user. The problem is that the code using userInfo (as in e.g. the alert) will always run before the userInfo variable has been filled and userInfo will return undefined/null.
I then proceeded to always create a new firebasesimplelogin object when i want to retrieve user data. Which of course isn't very good. Especially since every created FirebaseSimpleLogin object will be called again whenever another is called or a user logs out, for example.
So my question is, how do I use FirebaseSimpleLogin to handle and use my user information in the best way?
I would have liked some function to getUserInfo() or check isLoggedIn() for example. How do you do this properly?
You can take a look at this example for thinkster. It's based on using simple login with userid/password. http://www.thinkster.io/angularjs/4DYrJRxTyT/7-creating-your-own-user-data-using-firebase.
You can create a function like getLoggedinUser that runs in $rootScope that will allow you to find the user throughout the application.
UPDATE:
Around the middle of October 2014, firebase made some big changes. This method might still work, but it's better to take advantage of the newer version of firebase, specifically getauth and onauth. These methods will allow you to do the same thing without running on the rootScope. https://www.firebase.com/docs/web/guide/user-auth.html#section-login
Please make a constant to use it everywhere in your App like that
.constant('facebookUrl', 'https://rjrestaurantapp.firebaseio.com');
Then in the controller inject this constant "facebookUrl & "$state" as shown below...
.controller('loginCtrl', function($scope,facebookUrl,$state){
and then you only need to give name of the state where you want to redirect after facebook authentication..
var ref = new Firebase(facebookUrl);
$scope.fbLogin = function () {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
$state.go('restaurant');
}
})
}})
You can see the information in authData object after successfull authentication using facebook ....
please read this doc carefully https://www.firebase.com/docs/web/guide/login/facebook.html
The above is the example of simple login using firebase and for retrieving data for each logged in user, you have to store user information at the time of signin as you know that firebase makes every child with a unique ID .. then you only need to use the offline features of firebase that will find which user is offline and according to that remove the node with the same ID which one is offline, you can find examples in the MANAGING PRESENCE section of the below link ..
https://www.firebase.com/docs/web/guide/offline-capabilities.html

Categories