Firebase security rules check multiple references - firebase

I am developing an application in which I need a set of users (employees) belonging to a group (store) to only be able to read from the "Customers" table if these customers have an order placed by an employee in the same store.
This is my structure thus far (top level are collections):
Users: [
{id: 1, name: "John", store: "a"},
{id: 2, name: "Jane", store: "a"},
{id: 3, name: "Charles", store: "b"},
],
Stores: [
{id: "a", name: "Store A"},
{id: "b", name: "Store B"},
],
Customers: [
{id: "1", name: "Customer 1", ...data},
{id: "2", name: "Customer 2", ...data}
],
Orders: [
{id: "001", customer: "/Customers/1", employee: "/Users/1"},
{id: "002", customer: "/Customers/2", employee: "/Users/3"}
]
In this example, John and Jane should be able to see the Customer 1 but not the Customer 2, and Charles should be able to see the Customer 2 but not the Customer 1.
I tried to make a function to do this, like so:
function canSeeCustomers() {
if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.store == ?
}
But I don't know how to check the store field against the Orders collection.
Is there any way to do this? Or would I be better refactoring the DB structure to make Users a subdocument of Stores?

Add stores to your customers data too. stores: {a: true}.
So you could do
allow read: if resource.data.stores[get(/databases/$(database)/documents/users/$(request.auth.uid)).data.store];

Related

Angular Access list Properties [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
In myI have cities withidandnameandcounteyidand countries withidandnamehow to iterate thisresponse.valueto get a list havingcityid,name,countryid`?
you can use map function I guess, here some example with your code. I extend your list like that and result shown below
const value = [
{
id: "1",
name: "cityname",
countryId: "countryId",
countries: [{ id: 1, name: "countryname" }],
},
{
id: "2",
name: "cityname-2",
countryId: "countryId-2",
countries: [{ id: 2, name: "countryname-2" }],
},
{
id: "3",
name: "cityname-3",
countryId: "countryId-3",
countries: [{ id: 3, name: "countryname-3" }],
},
];
// you can check your list result
console.log(
value.map((m) => ({
cityId: m.id,
cityName: m.name,
countryId: m.countryId,
}))
);

Differentiation between normal users and bots in Telegram

Say I have created a group in Telegram and want to develop a bot and add it to the group as an admin. Now, say this bot is programmed to send a welcome message to the users joining the group. However, we want to send the welcome message only to actual human users, and not to other bots that might have been added to the group. Is this technically possible? I mean, when I'm developing my admin bot, how can I make it able to differentiate between a user and a bot? Is there a query or something for that?
your bot gets a JSON object as a new user joins your group:
{
message_id: 8,
from: {
id: <user_id>,
is_bot: false,
first_name: 'A',
last_name: 'B',
username: '<adder_username>'
},
chat: {
id: <chat_id>,
title: 'test',
type: 'supergroup'
},
date: 1535443550,
new_chat_participant: {
id: <user_id>,
is_bot: false,
first_name: 's',
username: '<added_username>',
language_code: 'en-us'
},
new_chat_member: {
id: <user_id>,
is_bot: false,
first_name: 's',
username: '<added_username>',
language_code: 'en-us'
},
new_chat_members: [{
id: <user_id>,
is_bot: false,
first_name: 's',
username: '<added_username>',
language_code: 'en-us'
}]
}
checking msg.new_chat_participant.is_bot you can find out if it is a real user or a bot.

How to map API response to database state in Redux-orm

I am trying to directly map API response to my Redux-Orm models. I have two models:
Product hasMany ProductProperties
ProductProperty belongsTo Product
The API response I receive is:
{
products: [
{name: 'P1', id: 1},
{name: 'P2', id: 2}
],
product_properties: [
{name: 'Test1', id: 10, product_id: 1},
{name: 'Test2', id: 11, product_id: 1},
{name: 'Test3', id: 12, product_id: 2}
{name: 'Test4', id: 13, product_id: 2}
]
}
I can tweak the API response to match with the redux-orm.
My Question is:
I want to avoid doing ProductProperty.first().set({product: Product.first}) -- That is I don't want to set the associations (child records) explicitly and have redux-orm infer them automatically.
Is there some way I can specify the foreign key that redux-orm can look for?
What I recommend to you is to use a json api standard for your API.
That way, in your API return, your products would have a relationships key that will help you map it to the included product_properties. Something like:
{
data: [
{
type: 'product',
id: 1,
name: 'P1',
relationships: [
product_property: [
{
data: {type: 'product_property', id: 10}
},
{
data: {type: 'product_property', id: 11}
}
]
]
},
{
type: 'product',
id: 2,
name: 'P2',
relationships: [
product_property: [
{
data: {type: 'product_property', id: 12}
},
{
data: {type: 'product_property', id: 13}
}
]
]
}
],
included: [
{type: 'product_property', name: 'Test1', id: 10},
{type: 'product_property', name: 'Test2', id: 11},
{type: 'product_property', name: 'Test3', id: 12}
{type: 'product_property', name: 'Test4', id: 13}
]
}
That way, it would be much easier for you to make a standard API parser that would map your json api resources to your redux-orm store. You create a redux-orm resource for each product and each product_property. Than you loop over product relationships and link them.
Hope that would help.
Best

Normalize different collections with a pre-flatted array a.k.a. joins

All normalizr examples are focused on nested objects they are expecting an API result that looks like this:
{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}
But I actually found that the following format where you have to do the collections joins yourself is the one I'm dealing with the most, can I use normalizr to handle this case for me?
Posts [{ _id: 1, name: 'post text 1', userId: 5, locationId: 8}]
Locations [{ _id: 8, name: 'New York'}]
Users [{ _id: 5, name: 'John Doe', country: 'US'}]
expected result:
{
results: [1], // posts ids
entities: {
posts: {
1: { name: 'post text 1', userId: 5, locationId: 8 }
},
users: {
5: { name: 'John Doe', country: 'US' }
},
locations: {
8: { name: 'New York' },
}
}
}
Docs/github issues nothing mentions it as far as I could find

How do I use Normalizr to handle basic nested JSON?

I have a very standard nested JSON response. Projects have many dashboards. Dashboards have many charts.
What is the right way to define and use my schemas?
Below is the code for my Schemas.js, my API response, and what Normalizr converts my API response into.
Schemas.js:
import { Schema, arrayOf, normalize } from 'normalizr';
// Create a schema for each model.
const project = new Schema('projects');
const dashboard = new Schema('dashboard');
const chart = new Schema('chart');
// Projects have many dashboards.
project.define({
dashboards: arrayOf(dashboard)
});
// Dashboards have many charts.
dashboard.define({
charts: arrayOf(chart)
});
export const Schemas = { project, dashboard, chart };
My API response:
{
projects: [{
id: 1,
name: "Project 1",
dashboards: [{
id: 1,
name: "Dashboard 1",
charts: [{
id: 1,
name: "Chart 1"
},
{
id: 2,
name: "Chart 2"
}]
},
{
id: 2,
name: "Dashboard 2",
charts: [{
id: 3,
name: "Chart 3"
},
{
id: 4,
name: "Chart 4"
}]
}]
},
{
id: 2,
name: "Project 2",
dashboards: [{
id: 3,
name: "Dashboard",
charts: []
}]
}]
}
When I receive this JSON in an action I do normalize(response, Schemas.project);. This seems to move the entire response into entities.projects.undefined.
{
entities: {
projects: {
undefined: {
projects: [{
id: 1,
name: "Project 1",
...
}, ...]
}
}
},
result: undefined
}
How should I correctly define and use my schemas for this?
References:
https://github.com/gaearon/normalizr
https://github.com/reactjs/redux/blob/master/examples/real-world/actions/index.js
This should give you the desired result:
normalize(response, {
projects: arrayOf(Schemas.project)
});
The projects key is nescessary because you have an extra key in your response, and the arrayOf() indicates that the API returns an array of results.

Resources