Developing a news feed of a sns with Firebase(NoSQL) - firebase

I’m trying to develop an app which is a social network service with firebase. Everything is alright. But, I got stuck when I think about news feed feature. Sure, I can find the posts user by user. But it's not cool and inefficient. Or, there is another idea. Create news feed document for the user, and add someone's posts when user follows or someone writes a post. But it is also not that good.
How could I make news feed feature with Firebase(or NoSQL, whatever)? I really want to know how to make news feed with NoSQL.

Actually Firebase blog explained about this on here.
{
"timeline": {
"user2": {
"-K-zOrtjiCGe7tgRk8DG": {
"text": "I love emojis!",
"uid": "user1"
}
},
"user3": {
"-K-zOrtjiCGe7tgRk8DG": {
"text": "I love emojis!",
"uid": "user1"
}
}
},
"followers": {
"user1": {
"user2": true,
"user3": true
}
}
}
It calls "Fan-out" process. And it's kind broad topic for NoSQL database environment.

Related

Firebase database structure for one-on-one messaging?

I'm relatively new to Firebase and I'm trying to figure out the best way to structure my DB for 1:1 chats.
It basically has to function like Whatsapp - you have your active conversations on the left when a person sends a message that conversation is then put on top of the list and a basic one-on-one chat on the right.
Right now the best that I have got is to create a firestore "chats" collection
chats : {
chat : { users : [user_id, user_id], messages : {user_id, message, created_at} created_at }
}
Would this solution allow me to :
Get all the chats based on the logged-in user?
Then Sort the returned chats by date?
Get the latest message from the messages collection for each returned chat?
On new message change the order of the chat and update the latest message?
And if all of that is doable would this be effective or is a there a better way?
Any help would be appreciated - thanks!
How would a logged in user be associated with any given chat they participated into?
Right now your structure doesn't seem to allow for an easy handling of this, given that "user_id" are nested within the chat document.
Personally, here's what I would do.
First I would create 2 collections, one called chats one called users.
users would have the following structure:
{"users": {
"userID_1": {
"name": "John",
"surname": "Smith",
"chats": [
"chatID_1",
"chatID_2",
"chatID_3"
]
},
"userID_2": {
"name": "Betty",
"surname": "Sue",
"chats": [
"chatID_1",
"chatID_4"
]
}
}}
Chats would instead be stored like this:
{"chats": {
"chatID_1": {
"chatName": "foo",
"otherInfo": "..",
"messages": {
"messageID_1": {"senderID": "..", "message": "..", "timestamp": 999},
"messageID_2": {"senderID": "..", "message": "..", "timestamp": 999}
}
},
"chatID_2": {
"chatName": "bar",
"otherInfo": "..",
"messages": {
...
}
}
}}
This way, when a user is logged in, you can easily fetch all his chats by querying users.userID.chats, and retrieve the content of any selected chat by querying chats.chatID.messages.

How to prevent malicious scripts writing to Firebase database?

I been reading firebase 3+ documentation for a while and I'm still wondering how to manage the following scenario regarding safety:
Let say I have a website for publishing local business like yellow pages in where everyone with an account can add new entries and edit the info of the existing ones with the following schema:
{
"businesses"": {
"62061635": {
"id": "62061635",
"name": "Cellphone store"
},
"66856728": {
"id": "66856728",
"name": "El Bambino restaurant"
}
}
}
If a user with a successful login write the following snipped in the developers console:
firebase.database().ref('/businesses/').once('value').then(function(snapshot) {
console.log(snapshot.val());
});
Practically all users could retrieve all the businesses info, that's not so drastic, but if instead of the above code the users use the following code:
var i=0;
while(i++ < 10) {
var id = generateRandomString();
firebase.database().ref('businesses/' + id).set({
id: id,
name: generateRandomString()
});
}
That's something I worry about, I know there are rules for database, but in this case where all users can add and edit the info, how can I prevent the users to run malicious scripts like the ones above?

Firebase Data Structure Guidance

I have been researching Firebase as an alternative to the recently deprecated Dropbox Datastore API. I read the articles about structuring data, but I’m still a little unclear.
I have a bunch of users:
users
- name
- email
...and each user has three database “tables”, aircraft, entries, and customFields.
aircraft
- name
- category
- make
entries
- flightDate
- departure
- destination
customFields
- name
- type
So would my Firebase data structure look something like this?
{
“users”: {
“bob”: {
“name”: …
“email”: …
},
“sally”: {
“name”: …
“email”: …
}
},
“aircraft”:{
???
},
“entries”:{
???
},
“customFields”:{
???
}
}
Thanks in advance.
Are you familiar with OOP? Each "table" is an object. Personally I would do something as follows. Since I don't understand what you're trying to achieve with the database and their objects, this may not be correct:
{
"user": {
"name": "bob",
"aircraft": {
"name": "name"
},
"entries": {
"flightdate": "27/05/2015"
}
}
}
Think in objects, not tables. Think parent and child.
But in your example, if each object (user, aircraft, entries etc.) was plurals, you can treat them as a "table", it would just be an array of objects:
{
"aircrafts":[
{
"id":1,
"name": "name"
},
{
"id":2,
"name": "name"
}
]
}
Edit: My first example was if each user had an aircraft, in retrospect it was silly, but my point still stands.

Triggering smart campaign and getting 603

I am trying to use Marketo smart campaign to send email data.
What I do is:
1) get or create Lead with addresse email
2) trigger smart campaign I've created with this lead_id and a couple of tokens I created on the folder containing the campaign.
That is, I am sending POST to https://.mktorest.com/rest/v1/campaigns/5826/trigger.json?access_token= with body
{
"input": {
"leads": [
{
"id": 2034349
}
],
"tokens": [
{
"name": "{{my.subject}}",
"value": "subj"
},
{
"name": "{{my.message}}",
"value": "the text"
}
]
}
}
And I get the response:
{u'errors': [{u'message': u'Access denied', u'code': u'603'}], u'requestId': u'c8f5#14c79fae723', u'success': False}
I was trying token names without "{{" and "}}", without "my." - the same result. The campaign exist and has this ID.
What's wrong here?
The role of the Marketo API user that you're using needs the "Execute Campaign" permission, and your current user is probably missing that permission. Unfortunately you can't edit the existing role. You'll need to create a new role, check that permission, and possibly also create a new API User.

Firebase Security API - Complex Data Structure - How to enforce relationships?

For the past few weeks i've been exploring Firebase and its features to build a web app, but I've kind of ran into a wall when it comes to security rules.
I've build a data structure on Firebase but I'm not sure if it follows best practices (if it doesn't, feel free to suggest anything different about it):
{
"groups" : {
<GROUP_KEY>
"name": "",
"rels": {
"users": {
<RELS_USERS_KEY>
"key":"" (USER_KEY)
},
"notes": {
<RELS_NOTES_KEY>
"key":"" (NOTE_KEY)
}
},
"isPrivate": true
},
"users": {
<USER_KEY>
"email": "",
"rels": {
"friends": {
<RELS_FRIENDS_KEY>
"key":"" (USER_KEY)
}
},
},
"notes": {
<NOTE_KEY>
"title": "",
"description": "",
"rels": {
"files": {
<RELS_FILES_KEY>
"key":"" (FILE_KEY)
}
}
},
"files": {
<FILE_KEY>
"mode": "",
"url": ""
}
}
The application flow is as follows:
The user signs up: a key is created on "users";
Is redirected to "Groups" view, where he should be shown only
groups that have his ID in RELS > USERS, or that has
"isPrivate":"false";
As the user creates a Group, a new group is added with his ID in RELS > USERS;
Entering the Group view, he should only see notes that are in RELS > NOTES for that group.
The rest of the logic follows the same principle, and I believe that if I can get through the first hurdle of understanding the Firebase security rules and applying them to this case, I can get through the rest.
I've tried a couple of rules, but I can't seem to get any feedback at all from the web application, debugging this has been a trial-and-error process, and its not really working.
Could someone help me at least understanding the logic behind it ? I've read all of their tutorials but they all seem very shallow with no deeper examples on complex structures.
Thanks for the help.
EDIT
I've added the debug:true flag to the login (thanks #Kato), but I'm still getting no feedback on the rules. With the rules as below, I still enter the "Groups" view, but get no feedback on the console, and the logged-in user sees groups he shouldn't:
{
"rules": {
"groups": {
".read": "data.child('rels').child('users/' + auth.user).exists()",
".write": "data.child('rels').child('users/' + auth.user).exists()"
}
}
}
As for the rules I've tried, they were countless, but this is the most recent one (still no feedback).
Maybe I'm missing something ?
Thanks again.
Rules cascade. That is, if any rule allows read, then you cannot revoke it later in a nested child. In this way, you can write rules like the following:
"$record": {
// I can write the entire record if I own it
".write": "data.child('owner').val() === auth.uid",
"foo": {
// anybody in my friends list can write to foo, but not anything else in $record
".write": "data.parent().child('friends/'+auth.uid).exists()"
},
"bar": {
// this is superfluous as permissions are only "granted" and never "revoked" by a child
".write": false
}
}
Note how, because I am the owner, I can also write to foo and to bar, even though bar has tried to revoke my read privilege.
So in your case above, your rules declaration lists read: true which allows full read access to the entire repo. Change that to false and you'll see better results.

Resources