So I've come across this thread.
Structuring data for chat app in Firebase
I would just like to give a sample for my firebase db structure ( similar in firebase docs).
{
"chatMetadata": {
"chatroom_id_1": {
"title": "Some Chatroom Title",
"lastMessage": "Some Message",
"timestamp": 1459361875666
"users": {
"uid_1": true,
"uid_3": true
}
},
"chatroom_id_2": { ... }
},
"users": {
"uid_1": {
"chatRooms": {
"chatroom_id_1": true,
"chatroom_id_2": true
},
},
"uid_3": { ... }
},
"chatrooms": {
"chatroom_id_1": {
"m1": {
"name": "uid_1",
"message": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"m2": { ... }
},
"chatroom_id_2": { ... }
}
}
For me to implement like a recent chat messages. I'll probably need the "/chatMetadata/" data since it has the lastMessage
To query it in client we need the answer in the link above to get it in one reference alone.
//chatMetaDataRef = root of "chatMetadata"
chatMetaDataRef.queryOrderedByChild("users/uid_3").queryEqualToValue(true)
.observeSingleEventOfType(.Value, withBlock: { snapshot in
// Do something here
})
Problem with this is all users should have read access to "/chatMetadata" node for that to work.
Here is my security rule for it
{
"rules": {
".read": "auth.uid === 'someServiceWorker'",
".write": "auth.uid === 'someServiceWorker'",
"chatMetadata": {
"$chatroomId":{
".read": "data.child('users/'+auth.uid).exists()"
},
".read": "auth != null"
},
"chatrooms": {
"$chatroomId": {
".read": "root.child('chatMetadata/'+ $chatroomId + '/users/'+auth.uid).exists()",
}
},
"users": {
"$userId": {
".read": "auth.uid === $userId"
}
}
}
}
Now my question is how should we implement the security rule for this one such that users shall not have access to all chatMetadata(because if i remove "auth!=null", my query above will not work. Or if it is not possible how should we restructure the data such that we can query it with one reference alone?
P.S.
Reason for the question is I didn't like the idea that I will loop over "users/$uid/chatrooms" and query each reference I receive from it. Like the 2nd answer in the link above.
for chat in listOfChatsUserIsIn
ref.child("chatMetadata").child("\(chat)").child("lastMessage").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
lastMessage = snapshot
// do something here
}
Related
How can I GET the list of dependabot alerts available at https://github.com/{user}/{repo}/security/dependabot?page=1&q=is%3Aopen via the GitHub API?
I searched through the documentation but couldn't find anything there.
Thanks!
There is this RepositoryVulnerabilityAlert object available with the Graphql API.
For example for a specific repository, you can get all the alerts with the following query (check this out in the explorer) :
{
repository(name: "repo-name", owner: "repo-owner") {
vulnerabilityAlerts(first: 100) {
nodes {
createdAt
dismissedAt
securityVulnerability {
package {
name
}
advisory {
description
}
}
}
}
}
}
It also returns alerts that were dismissed which can be spotted using the dismissedAt field. But there doesn't seem to be a way to filter only "active" alerts
Sample output:
{
"data": {
"repository": {
"vulnerabilityAlerts": {
"nodes": [
{
"createdAt": "2018-03-05T19:13:26Z",
"dismissedAt": null,
"securityVulnerability": {
"package": {
"name": "moment"
},
"advisory": {
"description": "Affected versions of `moment` are vulnerable to a low severity regular expression denial of service when parsing dates as strings.\n\n\n## Recommendation\n\nUpdate to version 2.19.3 or later."
}
}
},
....
]
}
}
}
}
I have to store some users and their group relations like below
So I am planning to create a collection like below
UserGroupRelation Collections
{
"user":String,
"Group":String"
}
example of collections for Super admin users
{
"user":"Adminuser-1",
"Group":"Group1"
}
{
"user":"Adminuser-1",
"Group":"Group2"
}
{
"user":"Adminuser-1",
"Group":"Group3"
}
where user & Group column is indexed and I will run below kind of query
1.Whenever I want to check whether given user has access to the given group
db.UserGroupRelation.find( { user: "Adminuser-1", Group: "Group2" })
2.Also I want to delete all the association whenever we delete group
db.UserGroupRelation.deleteMany({ Group: "Group2" })
3.Also find all the users of a group
db.UserGroupRelation.find( { Group: "Group2" })
4.Find Hierarchy?, with my Approach I am not able to find
But with this approach I am duplicating lot of data also in real time I may have 10000 groups and 1 million user so there would be performance issue. And with this I am not able to maintain a hierarchy like SuperAdmin->SubAdmin->user of same group
I checked with mongo tree but it is not fitting to this requirement. is there a better way to handle this requirement in mongodb .?
This is the structure your graphic requirements show. It does still lead to repetition though so you will need to change it. Read up on one-many relationships.
{
"superAdmin_ID": "001",
"groups": [
{
"_id": "0",
"groupNumber": "1",
"users": [
{
"_userKey": "1023"
"userName": "Fred"
},
{
"_userKey": "1024"
"userName": "Steve"
}
],
"subAdmin": {
"_adminKey": "55230"
"adminName": "Maverick"
},
},
{
"_id": "1",
"groupNumber": "2",
"users": [
{
"_userKey": "1023"
"userName": "Fred"
},
{
"_userKey": "4026"
"userName": "Ella"
}
],
"subAdmin": {
"_adminKey": "55230"
"adminName": "Maverick"
},
},
{
"_id": "2",
"groupNumber": "3",
"users": [
{
"_userKey": "7026"
"userName": "James"
}
],
"subAdmin": {
"_adminKey": "77780"
"adminName": "Chloe"
},
},
]
}
You can also make subAdmin an array if you need more than one subAdmin within a group.
I am using firebase in swift to read some data from firebase realtime database. When I had one project in firebase panel its work fine, but after adding another project today I got error like this
2017-09-23 00:15:18.360 AfgDate[2816] [Firebase/Database][I-RDB034028] Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "date" at /data to your security rules for better performance
This is my database structure
my role was
{
"rules": {
".read": true,
".write": true,
}
}
after that i changed my roles to this one
{
"rules": {
"data": {
".indexOn": "date",
".read": true,
".write": true
}
}
}
in this time also i cant read data and and i didn't see any error in console
this is my code in swift
ref = Database.database().reference()
ref.child("data").queryOrdered(byChild: "date").queryEqual(toValue: "1396/06/05").observeSingleEvent(of: .value, with: { (snapShot) in
if let snapDict = snapShot.value as? [String:AnyObject]{
for each in snapDict{
let key = each.key as String
let date = each.value["date"] as!String
let name = each.value["text"] as! String
print(key)
print(name)
self.lblshow.text = name
}
}
}, withCancel: {(Err) in
print(Err.localizedDescription)
})
how
*Please, study the comments to know how the problem was actually solved.
Try this, and with the same Data(with capital "D") in rules as well as in your query like Jen suggested .
{
"rules": {
".read": true,
".write": true,
"Data" : {
".indexOn": "date"
}
}
}
And try this
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
instead of
ref = Database.database().reference()
The image of your database shows Data as capitalized, but your .indexOn data isn't. You want your rules to be like this:
{
"rules": {
"Data": {
".indexOn": "date",
".read": true,
".write": true
}
}
}
I tested a couple rules myself just now and found out that they are case sensitive.
I try to come up with a Firebase realtime DB structure for an online store.
The store should have a collection of products, each product can belong to one or more categories. Is it possible to construct a query to get all products in the computers category with a single HTTP request (assuming I use Firebase REST API)? Here is a sample piece of data:
{
"products": {
"-KaXxv2xD9WaIqHMsHYM": {
"title": "Item 1",
"categories": {
"electronics": true,
"computers": true
}
},
"-KaXyvdw5gmuBmGi5unb": {
"title": "Item 2",
"categories": {
"electronics": true
}
},
"-KaXyyyzmP9Y6askhLdx": {
"title": "Item 3",
"categories": {
"computers": true
}
}
}
}
I was also trying to use arrays for categories but looks like arrays support is very limited in Firebase and they should be avoided.
UPDATE:
This query works:
GET /products.json?orderBy="categories/computers"&equalTo=true
But it requires an index for every single category:
{
"rules": {
"products": {
".indexOn": ["categories/computers", "categories/electronics"]
}
}
}
You should have an additional categories node which have products list. That would make easier and efficient access to products for a specific category.
Similar aproach is used at Firebse sample. See code
childUpdates.put("/posts/" + key, postValues);
childUpdates.put("/user-posts/" + userId + "/" + key, postValues);
They have save same data at posts and user-posts nodes.
I am trying to find a way I could have a query for the users in my application. For example, if my user want to search for a user to add him as a friend. I think I can save all the users in the Firebase database, and then perform a query in the database, but it look very inefficient(and there must be a easier built in method to do it).
".indexOn" is the solution for you!!
If you structure you date like below you would be able to query user!! Here you are able to query user on full_name and reversed_full_name. You can provide whichever child you want to query on. For instance, you can add email field under people and then add "email" in ".indexOn"!!!
"people": {
".indexOn": ["_search_index/full_name", "_search_index/reversed_full_name"],
".read": true,
"$uid": {
".write": "auth.uid === $uid",
"full_name": {
".validate": "newData.isString()"
},
"profile_picture": {
".validate": "newData.isString()"
},
"posts": {
"$postId": {
".validate": "newData.val() === true && newData.parent().parent().parent().parent().child('posts').child($postId).exists()"
}
},
"_search_index": {
"full_name": {
".validate": "newData.isString()"
},
"reversed_full_name": {
".validate": "newData.isString()"
}
},
"following": {
"$followedUid": {
".validate": "newData.parent().parent().parent().parent().child('followers').child($followedUid).child($uid).val() === true" // Makes sure /followers is in sync
}
}
}
Hope this helps. Here's the link to whole security rules, which is provided from Firebase https://github.com/firebase/friendlypix/blob/master/web/database-rules.json