How should I clear the Relay JS store when logging out? - relayjs

I'm using react-relay v12.
When logging out, should I create a new relay environment (rather than e.g. clearing the store somehow)? I have been doing just that, but I'm now having problems because the Relay environment in the RelayEnvironmentProvider context is not updated.
In theory I could manually update this using a hook, but this is difficult in certain places (e.g. relay network middleware, state containers)
The easiest solution seems to be to avoid creating a new store and instead clear the old one. Is that possible? Or is there a better solution?

Related

How to ensure the integrity of data sent to the database from my application?

I am currently creating an iOS application with Swift. For the database I use Firebase Realtime Database where I store among other things information about the user and requests that the user sends me.
It is very important for my application that the data in the database is not corrupted.
For this I have disabled data persistence so that I don't have to store the requests locally on the device. But I was wondering if it was possible for the user to directly modify the values of the variables during the execution of my application and still send erroneous requests.
For example the user has a number of coins, can he access the memory of the application, modify the number of coins, return to the application and send an erroneous request without having to modify it himself.
If this is the case then is it really more secure to disable data persistence or is this a misconception?
Also, does disabling access to jailbroken devices solve my problems? Because I've heard that a normal user can still modify the request backups before they are sent.
To summarize I would like to understand if what I think is correct? Is it really useful to prevent requests to save locally or then anyway a malicious user will be able to modify the values of variables directly during the execution and this without jailbreak?
I would also like to find a solution so that the data in my database is reliable.
Thank you for your attention :)
PS : I also set the security rules of the db so that only a logged in user can write and read only in his area.
You should treat the server-side data as the only source of truth, and consider all data coming from the client to be suspect.
To protect your server-side data, you should implement Firebase's server-side security rules. With these you can validate data structures and ensure all read/writes are authorized.
Disabling client-side persistence, or write queues as in your previous question, is not all that useful and not necessary once you follow the two rules above.
As an added layer of security you can enable Firebase's new App Check, which works with a so-called attestation provider on your device (DeviceCheck on iOS) to detect tampering, and allows you to then only allow requests from uncorrupted devices.
By combining App Check and Security Rules you get both broad protection from abuse, and fine-grained control over the data structure and who can access what data.

How to manage and reload multiple QuickFIX/J sessions independently?

I can configure multiple sessions in a single QuickFIX/J settings file and then start them all with a single SocketInitiator. But I would like to be able to modify the configuration of one or more sessions and then restart just those sessions without affecting any others.
I could do this by having multiple settings files and using one SocketInitiator per session. But it seems as though QuickFIX/J is not intended to be used this way. Would it cause me any problems?
It is perfectly fine to start up an Initiator per session. It is a matter of taste. In any case: having a separate Initiator per session is independent and will not affect the other sessions.
If you want to follow the approach with a single Initiator then you could try to add/remove sessions dynamically via createDynamicSession()/removeDynamicSession(). There still is some manual work though.
Find the Session that you want to reload. logout() and close() it.
Call removeDynamicSession() for that Session.
Get the settings for the SessionID that you want to reload from the running Initiator. Remove these from the running Initiator via removeSetting().
Then reload the settings from the settings file for the needed Session and put them to the settings of the Initiator.
Then call createDynamicSession() for the SessionID

Aren't PWAs user unfriendly if the service worker is not immediately active?

I posted another question as a brute-force solution to this one (Angular: fully install service worker before anything else) but I thought I'd make a separate one to discuss the use case for when a service worker is used as intended.
According to the service worker life cycle (https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle), the SW is installed but it's only active once you then reload the page (you can claim() the page but that's only for calls that happen after the service worker is installed). The reasoning is that if and existing version is updated, the old one and the new one do not mix states and caches. I can agree with that decision.
What I have trouble understanding is why it is not immediately active once it is initially installed. Instead, it requires a page reload unless you explicitly define precaching rules in the SW. If you define caching rules with wildcards, it's not possible to precache those so you need the reload.
Given a single page PWA (like Angular), a user will discover the site and browser around on it but the page will never be reloaded during that session. If they then want to use the site offline later, they need to have refreshed or re-opened the tab at least one other time. That seems like a pretty big pitfall to me.
Am I missing something here?
Your understanding of the service worker lifecycle is correct but I do not think the pitfall you mentioned is as severe as you think it is.
If I understand you correctly, the user experience will only be negatively affected if the user loses connectivity during the initial browsing of the page (before the service worker is active) and is missing an offline asset. If this is truly a scenario you want to account for then that offline asset can be pre-cached in the browser-side javascript. Alternatively, as you mentioned, you can skipWaiting() and claim() to make the service worker active without the user refreshing the page.

Read cookies from within a Service Worker?

I would like to read a cookie within my service worker to use it when setting up my caches, but can't find any way of doing it.
Is there any way of doing that, or will I need to duplicate cookie data into IDB or similar?
Currently, you can't access them. There's a discussion in the W3C ServiceWorker repo about adding methods to access them in the future.

How to tell the user to log in with relay?

Almost all of my graphql objects require that the user is authenticated to access them. If the user is not logged in, or their credentials are invalid, the server returns an error with a flag requireLogin set to true.
How can I intercept errors wherever they occur in Relay, capture this specific error, and then use it to update my state in redux (which will then show a message and a login box)?
The ideal place seems to be the NetworkLayer, but before I implement my own custom NetworkLayer is there a better existing solution (some sort of Relay-wide onError handler for example)?
You're likely looking for the renderFailure prop on your Relay Root Container. This gives you a place to handle errors that occur while fetching your data. If you're looking for errors directly relating to Relay Mutations, you can provider success and error handlers to Relay.Store.commitUpdate. I think those two should be capable of handling most scenarios.
You did mention using Redux along with Relay. I've not done any research into OSS projects combining these two tools, but Relay itself handles a lot of what Redux also handles and more. While Redux is great, I do think Relay is a more custom fit for GraphQL itself, and React, and I've not felt the need to find a spot for Redux in this stack, yet. It might complicate things.

Resources