Filter by another node? - firebase

Let's say that I have the following structure:
posts {
post_key_1 {
user_key: “key”
message: “message”
}
…
}
users {
user_key_1 {
location_key: true
}
…
}
Each user has a location.
How could I get the posts from a certain location (for pagination)? Is there a way to order the posts by the location in the users node?
One way would be to also include the location_key in the post nodes, but if the user decides to change his location and there are a lot of posts, there would be too much workload on the server.
In SQL, it would be something like select * from posts join users using(user_key) where location_key = 1
Thanks.

Related

Hasura: Rename relationship fields

I have renamed my GQL root fields, which works as described in the documentation.
Unfortunately, these names do not seem to be applied to relations - is this a bug or simply not possible?
Example: Two entities, "Categories" and "Projects", connected by a one-to-many relationship. I renamed the aggregation root fields to "CategoriesAggregate" and "ProjectsAggregate", which works as expected.
However, in the query "Catgeories" (select all) I am offered "Projects_aggregate" as available relationship, not "ProjectsAggregate" as expected.
Here is an example query to illustrate it:
query MyQuery {
Categories {
Projects_aggregate {
aggregate {
count
}
}
id
}
ProjectsAggregate {
aggregate {
count
}
}
}
Is there any way to adjust this?
Thanks

Firestore Many to Many Relationships

Would like suggestions related to a many to many structure with roles/permissions.
We need a structure that permits users to belong to many organizations and users have a role/permissions for each organization. For example, User1 belongs to ABC CO as Admin, and User1 belongs to XYZ CO as Guest
We have solved this issue as follows:
organizations (collection) {
ABC (doc) {
permissions (object): {
User1DocID (object): {
admin: true
}
}
}
XYZ (doc) {
permissions (object): {
User2DocID (object): {
guest: true
}
}
}
}
This way you can configure the rules like this:
match /origanizations/{origanization} {
allow update, read: if resource.data.permissions[request.auth.uid].admin == true;
allow read: if resource.data.permissions[request.auth.uid].guest == true;
}
For the resources of the organization you would have to store the Organization ID in the specific docs (obviously). Then you can setup the rules for them as follows:
match /origanizationRessources/{origanizationRessource} {
allow update: if get(/databases/$(database)/documents/organizations/$(resource.data.organizationId)).data.permissions[request.auth.uid].admin == true;
}
You can also easily query for data that the user has specific permissions on with this design.
Please note: This design fits our purposes as we have a finite, straightforward number of users assigned to the organizations. If you are unsure, have a look at the limits in terms of document sizes (see https://firebase.google.com/docs/firestore/quotas) to find out whether you have to rely on another design. If you happen to be in the position of potentially hitting those limits, consider a seperate mapping collection.

How to keep two paths in sync in firebase?

I have a complex application and I am using Firebase for my backend data.
I have an object that is used in two different contexts, one for viewing by the user and one for the server to do batch processing. Something like this:
users: {
USER_ID: {
...
txns: {
TXN_ID: {
// data I need
}
}
}
...
},
transactions: {
TXN_ID: {
USER_ID: {
// data I need
},
USER_ID2: {
// different data I need
}
}
}
In relational terms, txn_ids and user_ids are in a many-to-many relationship. So looking through the transactions node to find all the transactions that belong to a user is hard in FB and looking though all the users to find a transaction id is hard in FB. So I denormalize the data. I think this is correct.
But how do I keep them in sync?
I've been using MPUs, which is fine, but I'm worried about it being prone to bugs in the future.
I've considered writing a Firebase Cloud Function to keep them in sync, but I'm worried about that being more fragile than MPUs.
Advice?

How to fan-out/distribute 500,000 records with Firebase?

Requirements:
Users can register to company & unsubscribe freely.
Users should get only the posts of companies they are registered to.
Users shouldn't see posts they already liked/disliked
Currently, what we are doing is, when a user joins a company, we copy the relevant posts to the user User_Feed, and the client fetches the posts.
Now assume we have 40K posts & 500K users. Each user that joins a company, we need to copy 40K of data to the user feed. Or when a company posts a new post, we need to build a huge fan-out object to pass to 500K USER_FEEDs.
This is not scalable.
David East in his post states that the fan-out technique supports millions of records, but even in his example, how can he handle 1M followers?
We feel like we're going about it the wrong way.
Is there a better solution to our problem?
We currently have the following structure:
Companies(~20 companies)
{
companyId: {
...comanyInfo
}
}
Users (~500K users)
uid: {
...userInfo
}
User_Companies (500k * max(20 companies))
uid: {
company1: true,
company2: true,
....
}
Company_Users (20 * max(500K users))
companyId: {
uid1: true,
uid2: true,
....
}
Company_POSTS (2K posts/company)
{
companyId: {
postId: {
...postInfo
}
}
}
User_Feed (For each user (500K))
{
uid:
posId : {
like: true
}
}
This post is also opened in Firebase Google Group

Is there a suitable hook for intercepting all POSTs to an OpenACS/AOLServer system?

I'd like to disable all POSTs to an OpenACS/AOLServer installation. Is there an good singular place – a request-hook or wrapper/middleware – to do this?
(Bonus points if the intercept can let a few URI patterns or logged-in users through.)
Yes, this is straight forward to do. You have a choice here: you can register a proc to run instead of all POSTs, or can you register a filter to run before the POST and filter out certain users or whatever. I think the filter is a better choice.
To do this you register your proc or filter using ns_register_proc or ns_register_filter (with preauth). Put the following code in a .tcl file under the tcl folder of an OpenACS package or under the main AOLserver /web/servername/tcl directory.
Filter example:
ns_register_filter preauth POST / filter_posts
proc filter_posts {} {
set user_id [ad_verify_and_get_user_id]
set list_of_allowed_user_ids [21 567 8999]
if {[lsearch -exact $list_of_allowed_user_ids $user_id] == -1 } {
#this user isn't allowed - so redirect them
ns_returnredirect "/register/"
# tell AOLserver to abort this thread
return filter_return
} else {
# this user is allowed, tell AOLserver to continue
return filter_ok
}
}
Proc example:
ns_register_proc POST / handle_posts
proc handle_posts {} {
ns_returnredirect "http://someotherwebsite.com"
}

Resources