Gifted Chat disorganized messages - javascript

I have a problem with GiftedChat, the messages appear completely disorganized in the app and even looking for messages directly from the firebase (where it is correct), the app does not get a logical order. When sending is organized, however the problem is when you load the messages. I'm completely lost
loadMessages = async () => {
const { user } = this.props;
const matchId = this.props.navigation.getParam('matchId');
const data = (await firebase.database().ref(`matchs/${matchId}/messages`).limitToLast(300).once('value')).val();
let messages = [];
if(data){
Object.keys(data)
.forEach(messageId => {
let message = data[messageId];
if(_.get(message, 'user._id') !== user.uid) _.push(message);
messages.push(message);
});
}
this.setState(() => ({
messages,
}));
}
My JSON:
{
"-LkAMYoS3fySk46Pbpan" : {
"_id" : "f5ba3d9a-c346-4f79-b371-c5d54798567e",
"createdAt" : 1563558815857,
"text" : "First message",
"user" : {
"_id" : "BVY4MDwSaaSDI2bAGjwkZlYktsK2",
"avatar" : "https://firebasestorage.googleapis.com/v0/b/wefound-760f2.appspot.com/o/users%2FBVY4MDwSaaSDI2bAGjwkZlYktsK2%2Fphotos%2Fk1xuqv26wdrjxoxmp8m.jpg?alt=media&token=7c16a0e4-2cb8-45a5-83a4-635d49c71180",
"name" : "Rafael"
}
},
"-LkAMZiITDxHE1WfCBGC" : {
"_id" : "c2755b48-136d-4a68-b283-377ebac7df8e",
"createdAt" : 1563558819564,
"text" : "Second message",
"user" : {
"_id" : "BVY4MDwSaaSDI2bAGjwkZlYktsK2",
"avatar" : "https://firebasestorage.googleapis.com/v0/b/wefound-760f2.appspot.com/o/users%2FBVY4MDwSaaSDI2bAGjwkZlYktsK2%2Fphotos%2Fk1xuqv26wdrjxoxmp8m.jpg?alt=media&token=7c16a0e4-2cb8-45a5-83a4-635d49c71180",
"name" : "Rafael"
}
},
"-LkAM_l4o_w_QeCsYRc8" : {
"_id" : "65772152-afd9-4353-b752-ac65978a536d",
"createdAt" : 1563558823838,
"text" : "Third message",
"user" : {
"_id" : "BVY4MDwSaaSDI2bAGjwkZlYktsK2",
"avatar" : "https://firebasestorage.googleapis.com/v0/b/wefound-760f2.appspot.com/o/users%2FBVY4MDwSaaSDI2bAGjwkZlYktsK2%2Fphotos%2Fk1xuqv26wdrjxoxmp8m.jpg?alt=media&token=7c16a0e4-2cb8-45a5-83a4-635d49c71180",
"name" : "Rafael"
}
},
"-LkAMcSSTOP7L1CwyiU4" : {
"_id" : "e69f3a72-0f4e-4c06-a763-518ef1984aa0",
"createdAt" : 1563558834859,
"text" : "Fourth message",
"user" : {
"_id" : "BVY4MDwSaaSDI2bAGjwkZlYktsK2",
"avatar" : "https://firebasestorage.googleapis.com/v0/b/wefound-760f2.appspot.com/o/users%2FBVY4MDwSaaSDI2bAGjwkZlYktsK2%2Fphotos%2Fk1xuqv26wdrjxoxmp8m.jpg?alt=media&token=7c16a0e4-2cb8-45a5-83a4-635d49c71180",
"name" : "Rafael"
}
},
"-LkAMduvBrEnUG6POGKt" : {
"_id" : "897b2042-25dc-46ec-a5f3-5bdc1fc355dd",
"createdAt" : 1563558840853,
"text" : "Fifth message",
"user" : {
"_id" : "BVY4MDwSaaSDI2bAGjwkZlYktsK2",
"avatar" : "https://firebasestorage.googleapis.com/v0/b/wefound-760f2.appspot.com/o/users%2FBVY4MDwSaaSDI2bAGjwkZlYktsK2%2Fphotos%2Fk1xuqv26wdrjxoxmp8m.jpg?alt=media&token=7c16a0e4-2cb8-45a5-83a4-635d49c71180",
"name" : "Rafael"
}
}
}
I gave console.tron.log () in the messages and they appear disorganized exactly the same is in the app, the problem is in the component?
1 - refers to the function that loads the messages.
2 - JSON file

There are two steps to ordering the data:
Telling the Firebase Database server to return the child nodes in the correct order.
Maintaining that order in your client-side code.
As far as I can tell your code does neither of these, which means the nodes end up in whatever order your client uses for JSON properties (which are by definition unordered).
Let's first see how to retrieve the data in the correct order from Firebase:
const snapshot = (await firebase.database().ref(`matchs/${matchId}/messages`).orderByChild('createdAt').limitToLast(300).once('value'));
The above orders all child nodes by the value of their createdAt property, then returns the last 300 in order to the client.
You'll note that I don't call val() here yet. The reason for that is that snapshot.val() returns a JSON object, and properties in a JSON object have no defined order. So if you call .val() too early, you lose the ordering information that the server returned.
Next up is processing them in the client-side code to not lose that order, which depends on using DataSnapshot.forEach():
data.forEach((message) => {
messages.push(message.val());
})

Finally, I am able to solve this problem by sorting the JSON which is coming to from the server based on the date and time(CreatedAT).
If the JSON data stored in a variable called discussion then your code should be
discussion.sort(function compare(a, b) {
var dateA = new Date(a.createdAt);
var dateB = new Date(b.createdAt);
return dateB - dateA;
});
In your case, data or messages is the one which holds the JSON. Add this code once you get the code in JSON format.
Thank you.

Related

Sending the result of a mongoDB view to another collection ( INSERT....SELECT from SQL )

I could create a big query, and turn it into a view. Let's call it DBA_VIEW.
db.DBA_VIEW.find()
I'm using noSQLbooster to interact with mongodb and I'm trying to insert the result of this view into another collection.
I don't want to "right click > export" because I need to do this via noSQLbooster itself.
I've seen some querie sthat can do the trick, but, as a SQL SERVER dba, I think I can't get the logic behind, let's say, this one below:
db.full_set.find({date:"20120105"}).forEach(function(doc){
db.subset.insert(doc);
});
how can I use such approach to do my taks?
I just need the result of that view from a collection, to be inserted in another collection, then after this we are going to export the data into a .json file or even a .TXT.
You can design the query in the following way so that the output is directly inserted in a new collection('subset' in this example) without iterating through the result set.
db.full_set.aggregate([
{
$match:{
"date":"20120105"
}
},
{
$out:"subset"
}
])
If 'full_set' has the following documents:
{
"_id" : ObjectId("5d423675bd542251420b6b8e"),
"date" : "20130105",
"name" : "Mechanic1"
}
{
"_id" : ObjectId("5d423675bd542251420b6b8f"),
"date" : "20120105",
"name" : "Mechanic2"
}
{
"_id" : ObjectId("5d423675bd542251420b6b90"),
"date" : "20120105",
"name" : "Mechanic3"
}
With the above query, the 'subset' collection would be having the following documents:
{
"_id" : ObjectId("5d423675bd542251420b6b8f"),
"date" : "20120105",
"name" : "Mechanic2"
}
{
"_id" : ObjectId("5d423675bd542251420b6b90"),
"date" : "20120105",
"name" : "Mechanic3"
}

How to handle nested firebase queries and to update ionic view asynchronously?

I was just wondering if someone could help me with an issue I'm having in my Ionic app.
I'm having trouble getting my head around nested firebase queries and being able to update the ionic view asynchronously. I'm not using angularfire or anything like that.
My database structure is the following...
"posts" : {
"-KguJ95gTreWH5AT5lQ1" : {
"category" : "Example",
"description" : "This is a test description!!!",
"userID" : "SeMpRKxczcSCFpnkVDTU2pxCDV12"
},
"-Kh--WhNsWAXqs1jLfXu" : {
"category" : "Example 2",
"description" : "Test description .....",
"userID" : "SeMpRKxczcSCFpnkVDTU2pxCDV12"
}
},
"user-posts" : {
"SeMpRKxczcSCFpnkVDTU2pxCDV12" : { // User ID
"-KguJ95gTreWH5AT5lQ1" : { // Post
"category" : "Example",
"description" : "This is a test description!!!",
"userID" : "SeMpRKxczcSCFpnkVDTU2pxCDV12"
},
"-Kh--WhNsWAXqs1jLfXu" : { // Post
"category" : "Example 2",
"description" : "Test description .....",
"userID" : "SeMpRKxczcSCFpnkVDTU2pxCDV12"
}
}
}
And my call to the database is the following...
const posts: Post[] = [];
this.database.ref('posts').orderByChild('category').equalTo(this.category.name).once('value')
.then(
(posts) => {
//console.log(posts.val());
posts.forEach(function(childPost) {
var post = childPost.val();
var user = {};
firebase.database().ref('users/'+post.userID).on('value', function(snapshot){
user = snapshot.val();
// console.log(user);
});
var newPost = new Post(childPost.key, post.category, post.description, user );
//console.log(JSON.stringify(newPost));
posts.push(newPost);
});
}
).catch(
(err) => {
console.log(err);
}
);
The problem I'm having is that my view is rendered before the data from the second query is resolved. I have to leave the view and re-enter for the change detection to update my view.
I've read about things such as nested observables etc, but that just seems like overkill for what I'm trying to do ( Or I may be wrong ). Any help would be appreciated?

Firebase retrieve data from a list of children without knowing the keys (Web)

I am working on a web application that allows some users to send others push notifications. The list of users "subscribed" to any one user is stored in a firebase database, the structure is as follows;
senderUserID
senderSubscribers
subscriberOneID
token: subToken
subscriberTwoID
token: subToken
subscriberThreeID
token: subToken
Basically I need to store the list of tokens in an array in order to use each of them to specify the clients receiving a push notification.
Here is my javaScript that returns the subscriber list 'Node'. In my case senderSubscribers is actually 'players'
firebase.database().ref('/users/'+currentUserId+'/players/').once('value').then(function(snapshot){
var allPlayersNode = snapshot.val();
console.log(allPlayersNode);
});
Console.log looks something like
firstUserID:Object
regID: the first subscribers token
secondUserID:Object
regID: the second subscribers token
JSON code:
"emails" : {
"kylebehiels#hotmail" : "vlHVHcIetlZp7zS8mm6GcwoFRsB3",
"test#gmail" : "hJuVfpGTJvRyP4qsA6xyyvgQDay1"
},
"users" : {
"hJuVfpGTJvRyP4qsA6xyyvgQDay1" : {
"email" : "test#gmail.com",
"first_name" : "kyle",
"games" : {
"placeholder" : "placeholder"
},
"last_name" : "behiels",
"practices" : {
"placeholder" : "placeholder"
},
"regid" : "c_z_KWeWorU:APA91bHORVZqSph-HikfxtO2XjvMnwudIymORoSm9t3gupKZ1fFIZCLxGUbX5dsrYooHHpeEiPXhcXEMu5Eo5-nwF8bBjw-OTwSbn_rujTuPVaCDOXUKp9mzIYqeZq7SFMaWssZfyKj7",
"workouts" : {
"placeholder" : "placeholder"
}
},
"vlHVHcIetlZp7zS8mm6GcwoFRsB3" : {
"email" : "kylebehiels#hotmail.com",
"first_name" : "kyle",
"games" : {
"placeholder" : "placeholder"
},
"last_name" : "behiels",
"players" : {
"hJuVfpGTJvRyP4qsA6xyyvgQDay1" : {
"playerRegID" : "c_z_KWeWorU:APA91bHORVZqSph-HikfxtO2XjvMnwudIymORoSm9t3gupKZ1fFIZCLxGUbX5dsrYooHHpeEiPXhcXEMu5Eo5-nwF8bBjw-OTwSbn_rujTuPVaCDOXUKp9mzIYqeZq7SFMaWssZfyKj7"
},
"vlHVHcIetlZp7zS8mm6GcwoFRsB3" : {
"playerRegID" : "cvZj3hb_zkk:APA91bEcmKlDlC5VKOI6wc1BvRI5mGgmWFA3QuTR3jH48l9fz565RhY2PEXE2GkXyhKXgb67qu7ieRlWF403q6rQPi0-xgGIbfvOkhGzopfyTFLNQg7ADgNHFAd1YfwwesbHjL5IHLZd"
}
},
"practices" : {
"placeholder" : "placeholder"
},
"regid" : "cvZj3hb_zkk:APA91bEcmKlDlC5VKOI6wc1BvRI5mGgmWFA3QuTR3jH48l9fz565RhY2PEXE2GkXyhKXgb67qu7ieRlWF403q6rQPi0-xgGIbfvOkhGzopfyTFLNQg7ADgNHFAd1YfwwesbHjL5IHLZd",
"workouts" : {
"placeholder" : "placeholder"
}
}
}
}

User data structure with Firebase

I asked several times and nobody gives me proper answer. So in Firebase, is this the proper data structure?
{
"users" : {
"-JNNJ-0ErS6kX5AFkfM3" : {
"userUid" : "simplelogin:66",
"userId" : "66",
"email" : "fd2#sdsa.cz"
}
"accounts" : {
"-JLXe5iaH-TLSBu0RJqp" : {
"currency" : "-JLXe--zoxk1DdKa9mAT",
"description" : "account1",
"name" : "account1"
},
"-JNJdqZouwAfEzmCSHTO" : {
"description" : "asdasd",
"name" : "dsad"
},
"-JLgcjINbZni6luTuPSY" : {
"currency" : "-JLXe--zoxk1DdKa9mAT",
"description" : "fefef",
"name" : "bkkjsdds"
}
},
"categories" : {
"-JLgd4W8COP6zOlhNdq9" : {
"color" : "#c55353",
"account" : "-JLXe5iaH-TLSBu0RJqp",
"description" : "fds",
"name" : "dsfdsfds"
}
},
"records" : {
"-JNNK2hnJ99dZqRmfsjs" : {
"date" : "2005-09-28T10:48",
"amount" : 123,
"description" : "description",
"category" : "-JLgd4W8COP6zOlhNdq9"
}
}
},
}
If it's hard to read, there is explanation.
I have a user with a key. User has accounts > every account has categories (every category has a key from an account) > every category has records (every record has a key from a category.
So for example that one record (I am describing parameters):
record's key: -JNNK2hnJ99dZqRmfsjs
records belongs to category with the key: -JLgd4W8COP6zOlhNdq9
People from Firebase unfortunately didn't help me at all and I don't understand their single tutorial.
Is this the proper way to do so? I just want to have data for each user (nobody else can't see another user's data).
EDIT:
Is this correct? I know that post. But I still don't understand it.
In real world is this proper way?
users
-JNNK2hnJ99dZqRmfsjs (key of user1 for example)
name
id
etc
accounts
-JLgd4W8COP6zOlhNdq9 (key of some account)
name
description
-KFTf6W8COP6zOlhNdq9 (key of user - account belongs to user and account has users reference - the key)
Is this correct?
EDIT2:
Look at this:
awesome.firebaseio-demo.com
Anant has beautiful tree:
users
user1
name
user2
name
How did he do it? I thought I can work only with keys.
Firebase blog post - Denormalizing Your Data is Normal helps you with proper data structure.
The second question ("nobody else can't see another user's data) is about security rules - you have to determine who can read data.

Meteor requestPermissions

Hey guys actually i got two question.
1.Im tying to get user info here is a list of what info i want (using facebook API):
user_likes, friends_about_me, user_birthday, email, user_location, user_work_history, read_friendlists, friends_groups, user_groups
here is my code for that:
Template.user_loggedout.events({
"click #fb":function(e,tmp){
Meteor.loginWithFacebook({
requestPermissions :
['user_likes',
'friends_about_me',
'user_birthday',
'email',
'user_location',
'user_work_history',
'read_friendlists',
'friends_groups',
'user_groups']
},function (err){
if(err){
console.log("error when login with facebook " + err);
} else {
console.log("login with facebook succeeded");
}
});
},
})
but my i ends up creating a user object with just some of the fields (user JSON object from mongoDB, i inserted "xxx" at some fields just for security):
{
"createdAt" : 1378842117154,
"_id" : "mW7urf5yZPCm6HhNK",
"services" : {
"facebook" : {
"accessToken" : "xxxx",
"expiresAt" : 1383945305007,
"id" : "xxxxxx",
"email" : "xxxx",
"name" : "Boaz",
"first_name" : "Boaz",
"last_name" : "xxx",
"link" : "https://www.facebook.com/xxxx",
"username" : "boazmier",
"gender" : "male",
"locale" : "he_IL"
},
"resume" : {
"loginTokens" : [
{
"token" : "TcLnp9GSbDasNZNCj",
"when" : 1378842117154
}
]
}
},
"profile" : {
"name" : "Boaz xxxx"
}
}
clearly you can see that there is no record for friends_list, user_birthday and much more.
second question:
same thing with github - i requset this: user, public_repo, avatar_url, gist
but end up with:
{
"createdAt" : 1378843359664,
"_id" : "pJGwTepYe2Ps7hhnS",
"services" : {
"github" : {
"id" : xxxx,
"accessToken" : "xxxxx",
"email" : "xxxxx",
"username" : "boazhoch"
},
"resume" : {
"loginTokens" : [
{
"token" : "hbNLcuC85MKwBJBfb",
"when" : 1378843359664
}
]
}
},
"profile" : {
"name" : "xxxx"
}
}
so i end up with no avatar but when changing my code on server to:
Accounts.onCreateUser(function(options,user){
var accessToken = user.services.github.accessToken,result,profile;
result = Meteor.http.get("https://api.github.com/user", {
params: {
access_token: accessToken
}
});
if(result.error){
throw result.error
}
profile = _.pick(result.data,
"login",
"name",
"avatar_url",
"url",
"company",
"blog",
"location",
"email",
"bio",
"html_url");
user.profile = profile;
return user;
});
my user object get the avatar_url why is that? i know that meteor ships out with Account.createUser and by doing onCreateUser im overriding it but then, what is the porpse of requestPermissions? also i can have only one Account.onCreateUser function, so how do i make this function request different data from each service? ( i want to include facebook,google,github,twitter and meetup)
Do you want the data to be available on the client to anyone with JS skills? If so, on saving things to the user record: The easiest thing to do would be to add any new information to the profile object, possibly grouped under a facebook object when from facebook. The profile object already is all published to the client. http://docs.meteor.com/#meteor_user
user.profile.prefs.color = 'red'
To keep it confidential, as you find things that should not make it to the client, write and read them from routines on the server. See
Meteor.call()
You can find code for how to get more data in the user record from the server to the client and back, where you essentially publish more. I wouldn't worry until there is a reason the profile object is insufficient.

Categories