How to hide value from Firebase in multi part request iOS - ios

I'm using Firebase in my iOS app but I want to ensure a value is never sent from the server to the client.
Users in the app are shown to each other based on a score they have. So a user with a score of 5 will see other users who have a score of 5. I don't want to include this value in the request/response to Firebase.
Where I can manage the server I can have server side logic handle this by looking up the user on the server then calling a function that determines who has the same score and returning the relevant users without the client ever receiving the user score.
With Firebase my understanding is I'd have to send the value to Firebase in a query i.e. get all users with this user's score.
How can I do this without exposing the user's score? I want something along the lines of a node user_scores where I can query the current users score and then using this query another node users to return me the relevant users without having to nest the query on the client and thus expose the score in the request/response?
Many thanks!

Your understanding is pretty much on point, there is no way to make a "dynamic" query like this without actually exposing the varying parameter to the client.
Here are two ideas you could try to use as a workaround:
A variation of "security by obscurity": instead of exposing a single number, obfuscate that value in a way that makes guessing its purpose and other values an unpleasant experience; and share that with the client.
If you keep your users grouped by this key, not just as a flat list where this is a child node, you can use security rules to enforce that the user cannot read any other group than theirs.
(Note that this is also true for numerical values. Security rules are not filters.)
In a much more involved strategy, you could make the query static. Store and maintain a list of matching users per user, so the clients can load their own personal list without any varying parameters sans the UID.
(This is probably not really feasible if there is a lot of movement involved. But it might work in some edge cases.)

Related

Options for combining multiple Amazon Lex bots

I work in a large enterprise where multiple teams are developing Lex bots (on separate accounts). Each bot supports a different domain or application,. In some cases, it would be nice for a single user interface to ask a question without needing to know which bot to ask. Is there a way to federate bots, or to forward un-recognized intentions to 'backup' bots?
I feel like what I really want to do is treat each bot as a skill is treated in Alexa, except I'm in the position (through entitlements) to know which 'skills' would be appropriate for a given user.
The answer here is that you would need to develop a custom application that delivers a user's input to each of your company's array of bots.
You'd need to look at the NLU Confidence score from each Bot's response to decide which response is the most accurate to return to the user. Would also be worthwhile keeping some state in your app to remember which Bot the user is currently interacting with and defaulting to that Bot for successive user inputs. Should you reach a point where the confidence score is low, it might present a signal to you to test the user's input across the other Bots.
What you'll need to be aware of here is that your costs will increase with each additional Bot that you add. So, assuming you have 5 area-specific Bots, one inbound message from your user could result in 5 Lex calls. As you start moving into significant volumes of interactions, this could start proving to be an obstacle.
An alternative would be to use a custom fallback intent to invoke a Lambda function that calls your Bot orchestration function. Assuming that you're able to find the correct Bot to handle the user's query, you'd need to remember that so succesive messages now get routed to that Bot.

Sort by mutual connections in social-networking iOS application with data store in firestore

I am writing an application that will help users connect to each other based on a number of attributes (i.e. location, interests, etc). I am using firebase firestore to store all of my user data, which has fields like name, hometown, interests, classes, and connections, which is a list of UUID of the users they are connected to.
When I suggest other users for a user to connect with, I want to do so by the number of their mutual connections, however this is not explicitly a field in the database, since I would have to calculate and maintain that for every user in relation to every other user. Is there a way I can use firestore to query or order by a calculated property rather than a field in the database, or another way to store the mutual connections?
I know in theory I could pull all the users from the database and then locally calculate the number of mutual connections and sort the array, but that sounds horribly inefficient.
I have searched for existing solutions such as how facebook or linkedin would suggest friends or people you might know, but I can't find any concrete answers on how they did this, but those companies are not using firestore either. I am hoping someone has had this problem in the past and can help me out.
There is no way to perform a calculation on the data in a Firestore query. If you want to order or filter in a calculated value, you'll have to store that value in the database.
Typically you can either do this:
As you write the data from the client, you also update the calculated values.
In a Cloud Function that triggers when you write the data, and that then updates the calculated values.
In a Cloud Function that runs periodically, and that then updates the calculated values for all modified data.

How can I get the participants of a Vanity experiment?

tl:dr
Is there anyway to get something like Vanity.experiment(:landing).participants_for_option(:a) returning a array of users?
The long story
I'm using the gem Vanity with a Rails 4.2 application and it is working nicely, but I want to inspect further the behaviour of participants.
I tested what kind of page converted more users: A classical signup page versus a signup with order page. The classical signup page led to almost three times more signups, but I'm still in the dark in the sense that I don't know, among the signup-only-users, how many ordered a product.
It sounds like you're trying to understand more about how an experiment affects different parts of your funnel.
At the aggregate level, one way to do that may be to to use multiple metrics for your experiment at different parts of your funnel, e.g. track!ing both signups and then purchases.
Unfortunately, Vanity isn't set up very well to query for individual participants per alternative, because testing itself is aggregate. If you want to access alternatives per user, there are methods for that, for example, Vanity.playground.adapter.ab_showing(experiment, identity), see the docs.
If you're interested in doing more in depth analytical queries, it might be worth using the SQL adapter, the schema tracks per participant and you could join to other tables that hold data about purchases/etc.
Edit:
It looks like this has changed in the most recent version of Vanity:
https://github.com/alobato/vanity/blob/master/lib/vanity/playground.rb#L231
Vanity.playground.connection.ab_assigned(experiment_name, identity)
Vanity.playground.connection.ab_showing(experiment_name, identity)

Browse Decision Table in WODM or iLog

I have a situation that I have a system that communicate with iLog and it should show the values of decision table first column.
Can I get all the values of the first column in a decision table? Given that the values are distinct and unique.
If yes, What if I want to get the values of the next column under the scope of the first column field.
I need this behavior since I have an agreement creation system which must allow creation of agreement terms based on what is already implemented in iLog
There isn't a way to extract values from Condition Column. I had also came across such situation when but couldn't get through it. However, there is a work-around for the same.
My Problem was, for example, there are rules to determine whether the user group to which user belong is allowed to approve the policy? If not, then what are the other user groups allowed to approve this policy?
One simple solution was to maintain two tables, one for checking and another to determine allowed groups. This was not accepted since business needs to maintain same data in two tables. Had it been FICO BLAZE Advisor, the same would have been implemented in a single table.
However, there is always another way to a problem. What I did is following:
1. Created a single table to list all are the groups which can approve the policy i.e. adding user groups into a list in the action column. Placed this decision table in a Rule Task.
2. In the final action of rule task, checked whether the user type of the incoming user exists in the list of user types. If not, it means user is not allowed to approve the policy so send the entire list; otherwise, set the list to null and set Approval flag to True.
I hope this may help you to find an alternate solution which may address your problem. Sometimes, we need to look for some weird way to get our work done.
HAPPY RULE DEVELOPMENT. :)

Logging data changes for synchronization

I am looking for solution of logging data changes for public API.
There is a need to tell client app which tables form db has changed and need to be synchronised since the app synchronised last time and also need to be for specific brand and country.
Current Solution:
Version table with class_names of models which is touched from every model on create, delete, touch and save action.
When we are touching version for specific model we also look at the reflected associations and touch them too.
Version model is scoped to brand and country
REST API is responding to a request that includes last_sync_at:timestamp, brand and country
Rails look at Version with given attributes and return class_names of models which were changed since lans_sync_at timestamp.
This solution works but the problem is performance and is also hard to maintenance.
UPDATE 1:
Maybe the simple question is.
What is the best practice how to find out and tell frontend apps when and what needs to be synchronized. In terms of whole concept.
Conditions:
Front end apps needs to download only their own content changes not whole dataset.
Does not invoked synchronization when application from different country or brand needs to be synchronized.
Thank you.
I think that the best solution would be to use redis (or some other key-value store) and save your information there. Writing to redis is much faster than any sql db. You can write some service class that would save the data like:
RegisterTableUpdate.set(table_name, country_id, brand_id, timestamp)
Such call would save given timestamp under key that could look like i.e. table-update-1-1-users, where first number is country id, second number is brand id, followed by table name (or you could use country and brand names if needed). If you would like to find out which tables have changed you would just need to find redis keys with query "table-update-1-1-*", iterate through them and check which are newer than timestamp sent through api.
It is worth to rmember that redis is not as reliable as sql databases. Its reliability depends on configuration so you might want to read redis guidelines and decide if you would like to go for it.
You can take advantage of the fact that ActiveModel automatically logs every time it updates a table row (the 'Updated at' column)
When checking what needs to be updated, select the objects you are interested in and compare their 'Updated at' with the timestamp from the client app
The advantage of this approach is that you don't need to keep an additional table that lists all the updates on models, which should speed things up for the API users and be easier to maintain.
The disadvantage is that you cannot see the changes in data over time, you only know that a change occurred and you can access the latest version. If you need to track changes in data over time efficiently, than I'm afraid you'll have to rework things from the top.
(read last part - this is what you are interested in)
I would recommend that you use the decorator design pattern for changing the client queries. So the client sends a query of what he wants and the server decides what to give him based on the client's last update.
so:
the client sends a query that includes the time it last synched
the server sees the query and takes into account the client's nature (device-country)
the server decorates (changes accordingly) the query to request from the DB only the relevant data, and if that is not possible:
after the data are returned from the database manager they are trimmed to be relevant to where they are going
returns to the client all the new stuff that the client cares about.
I assume that you have a time entered field on your DB entries.
In that case the "decoration" of the query (abstractly) would be just to add something like a "WHERE" clause in your query and state you want data entered after the last update.
Finally, if you want that to be done for many devices/locales/whatever implement a decorator for the query and the result of the query and serve them to your clients as they should be served. (Keep in mind that in contrast with a subclassing approach you will only have to implement one decorator for each device/locale/whatever - not for all combinations!
Hope this helped!

Resources