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.
Related
I am using react naitve expo with firebase realtime database I have just a simple list of name, email address and score in my database I want to be able to pull the high score our so I do an order by child and I choose scores as the child and limit to first my snap shot brings back the correct entry but when I do a snapshot.key I get the child score but not the value which I want to take and add to state.
I gave tried snapshot.key.val() but that gives me null,
as does snapshot.child.val().
my databases
memory-game
{
"users" : {
"TtDcqyNkhXSUCpzHeI9jELo7DCl1" : {
"Score" : 51,
"first_name" : "Joe",
"gmail" : "watsonr#gmail.com",
"last_name" : "watson",
"locale" : "en",
"profile_picture":"https://lh5.googleusercontent.com/-616Zg1h61BA/AAAAAAAAAAI/AAAAAAAAAAA/
},
"dxuCP7if4hWFoP8iO69ndD7gOVq1" : {
"Score" : 25,
"first_name" : "jay",
"gmail" : "jayd#cmail.com",
"last_name" : "watson",
"locale" : "en",
"profile_picture" : "https://lh5.googleusercontent.com/-bzA9FCFRNqc/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3re5n7l6GrqFFQK8PnySQ3cPY6T9ug/s96-c/photo.jpg"
}
}
}
firebase.database().ref("users/score").orderByChild("score").limitToFirst(1)
.once("value",snapshot =>{
const data = snapshot.key.val("score")
console.log (data)
console.log("testing")
})
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.
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"
}
I am implementing search result view to my app.
I figured out that mongoose internally provide full text search function with $text.
I put the code below to Post.js
PostSchema.index({desc: 'text'}); //for example
Here's the code I put in my routing file route/posts.js
Post.find({$text: {$search : 'please work!'}}).exec(function (err, posts) {...})
The error message I come up with is below
Index with pattern: { _fts: "text", _ftsx: 1 } already exists with different options
Would there any body who know how to deal with this error and figure out?
Thanks you.
check on which field you have your text index defined. Right now mongodb allows only one text index per collection. so if you have defined a text index on desc column and try to use that index on some other column you are bound to get this error.
can you try to query your index and see on which column you created it. To get indexes you can do
db.collection.getIndexes()
and it will return something like this
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "some.ns"
},
{
"v" : 1,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "desc_text",
"ns" : "some.ns",
"weights" : {
"title" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}
]
now if you want to scope in other columns also to use this index simply drop this index
db.collection.dropIndex('desc_text');
and then recreate it by including all columns you want to be covered by text index,
db.collection.createIndex({
title:'text;,
body: 'text;,
desc: 'text',
...... and so on
});
I have a collection of a post when a user comment on a post it will be maintain in an embedded documents of named comments.Now a problem is I have to sent a push notification at every 2 hours like this You have 12 new comments on this post for an owner of this post.
Now after clicking on push notification it redirect me to that comments after seen those comments.Now if a new comments is against post then after 2 hours i will be getting like this You have 3 new comments on this post
You can see in my schema that i will maintain total_comments fields.Problem is how i managed this push notification time based and how to identify and maintain track record of new comments.Should i add some key in schema and write a cron jobs to send push notification
Any help would be appreciated
Here is my record
{
"_id" : ObjectId("57b3aa2db630347c1f9308b4"),
"updated" : ISODate("2016-08-30T05:05:18.301Z"),
"created" : ISODate("2016-08-17T00:05:01.354Z"),
"createdTimeStamp" : 1471392301,
"likes" : [],
"comments" : [
{
"created" : 1471935213,
"user" : ObjectId("57b33c810a56a0a81a9b50b7"),
"text" : "next party",
"_id" : ObjectId("57bbf2edee7a923c156c2f08")
},
{
"created" : 1471935612,
"user" : ObjectId("57b33c810a56a0a81a9b50b7"),
"text" : "its new party ",
"_id" : ObjectId("57bbf47cddd701302ba14fca")
},
{
"created" : 1471935717,
"user" : ObjectId("57b33c810a56a0a81a9b50b7"),
"text" : "its new again",
"_id" : ObjectId("57bbf4e5f934024c275f4f08")
},
],
"total_comments" : 3,
"consumer_id" : ObjectId("57b33c810a56a0a81a9b50b7") // Original User that receive notification
}
There is two way to count new comments I guess.
First :
Storing in your user schema a key lastVisit.
And then do something like db.posts.count({'comments.created': { $gte: $$$YOUR lastVisit$$$ }});
comments.created must become a date.
Second :
Storing a key read: boolean in comments and false by default.
Then every time a user read the notification change this value to true.
And then count the new comments like this db.posts.count({'comments.read': false})
Then I don't know the best choice between a cron task or a setInterval