Flutter: graphql_flutter FetchPolicy.noCache returns cached data from different user - flutter

I'm using the graphql_flutter package and am having an issue with what seems to be caching. The client passes over cached data from one user to another, even when the FetchPolicy is set to noCache.
I’ve outlined below what my graphql client setup looks like and then the custom method I use for sending a query to the server (it fetches the items favorited by the user). I’ve looked through the Policies in the official documentation and believe my setup is correct. The issue (and the steps to reproduce) are the following:
I sign in to my app with a test user account (using Amplify Cognito
for authentication) and add some items to the user's favorites list (with a
mutation request).
I then navigate to a ‘Favorites’ summary page,
where I call the below outlined fetchFavoritesData method to fetch
all the items that were favorited by the user. Works like a charm.
I then log out and create a completely new user account and log in with this new user (i.e. different
access token and all).
Before adding any items to the favorites list for this new user, if I check their ‘Favorites’ summary page, which calls the fetchFavoritesData method and should return null (because this user has yet to add any), the result actually returns the exact items that were favorited by the first user. Odd.
Been playing around with the Policies, tried different fetch policies and so on, but the problem remains. Am I missing something (sorry — totally new to this package) or could this be a bug?
GraphQLClient client = GraphQLClient(
link: link,
cache: GraphQLCache(), // declared cache here because I'm using the client for a few different requests, some where caching is preferred.
);
}
Future<void> fetchFavoritesData() async {
final QueryOptions options = QueryOptions(
document: gql(queryFavoritesData),
// only return result from network
fetchPolicy: FetchPolicy.noCache,
// ignore cache data if any
cacheRereadPolicy: CacheRereadPolicy.ignoreAll,
);
final QueryResult result = await GraphQLConfiguration.client.query(options);
}
26/8/2021 UPDATE:
I've migrated over to Firebase for authentication and the error is no longer occurring. Not sure whether the authentication package was the causation or just a correlation but this is no longer an issue.

Related

Get Firebase Dynamic Link Data from String Input url Flutter

Dynamic links work great for 98% of our users. However, there are still a group of users which have difficulty with them or do not know how to use them.
I want to add a feature which would let users paste their link into the app, and then we extract the data from the link and handle it normally. This will also serve as a backup for when the links are down or misbehaving. It will also allow our customer service team to get data from a link when customers share them with us.
The problem is, there doesn't seem to be a way to manually pass in a dynamic link to retrieve the dynamic data.
Does anyone know how this can be achieved?
Here is my attempt at your question.
I am assuming what you mean by the dynamic data is the underlying deeplink along with the parameters associated with the deeplink.
void dynamicLinkToDeepLink(String dynamicLinkString) async {
final details = await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(dynamicLinkString));
// your deep link can be accessed as follows
details!.link;
}
You have to safeguard the above code as you see fits when you use it. You will have to wrap FirebaseDynamicLinks.instance..... with a try catch block and you will also have to check if the value of the returned link is not null before acccessing details!.link

Firestore security rules request.auth is always null

I am unsuccessfully trying to tighten Firestore security with custom claims.
versions:
Firebase: ^9.6.9
Node: 16.14.0
Next: 11.1.0
I have verified that my custom claims are set as they work as expected for certain collections/requests, specifically ones coming from NextJs Server Side Rendered functions.
I have tried:
Refactoring every service to Firebase V9 instead of using compat.
Changing the firestore rules in production
setting up emulators (Note* I'm not using auth emulator)
adding debug() to security rules
signing out and back in again
request.auth.token (which is what the debug shows on other reqs)
as well as request.resource.auth.token as per These Docs (incorrect usage)
From the security rules debug - request.auth is null
Update:
I see from the rules usage on the firebase console that the rules were treated as errors and not denies.
I have found strange behavior.
I am successfully able to use custom claims for any collection other than 'blog'.
Successful rule matching tags:
I'm starting to think it has something to do with NextJs Server Side Rendering using getServerSideProps()
My code to retrieve blog entries:
export async function getServerSideProps(context) {
const posts: BlogPost[] | any = await GetBlogPosts();
return {
props: {posts}, // will be passed to the page component as props
};
}
interface extendedBlogPosts extends BlogPost {
['key']: string;
id: string;
}
interface BlogPageProps {
posts: extendedBlogPosts[];
userProps: {user: UserInfo; userData: UserData};
}
It sounds like the code in getServerSideProps runs in a trusted environment and accesses Firestore using an Admin SDK. If that is the case then the behavior you are seeing is expected, as the Admin SDKs access the database with elevated/administrative privileges and not as a specific user, and bypass all security rules.
Even if you're not using the Admin SDK, if that code runs in the server using the regular JavaScript SDK (or the one for Node.js, but not for administrative usage), your code is executing in a different environment than where the user signed in. So unless you've signed the user into the server-side code too, it will run without a signed in user, and thus the request.auth variable in your rules will be null.
The current user information is stored in request.auth, not in request.resource.auth as you are using in your first and last screenshots.

How can I resolve 400 bad request in Google Picker dialog in test application?

I'm running into trouble with test users and the Picker component in my web applicaton.
A subset of my test users are receiving a 400: The server cannot process the request because it is malformed when attempting to access the picker. Some of them experience a looping sign-in beforehand.
The picker is constructed in the following way inside of a useEffect in a React component:
// if there's a non-config related bug, I would imagine it must be related to getting the access token here.
const accessToken = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
const view = new picker.DocsView(picker.ViewId.DOCUMENTS);
view.setIncludeFolders(true);
const pickerDisplay = new picker.PickerBuilder()
.enableFeature(picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.addView(view)
.addView(new picker.DocsUploadView())
.setOAuthToken(accessToken)
.setDeveloperKey(apiKey)
.setCallback(pickerCallback)
.build();
setPicker(pickerDisplay); // sets picker state
Because I am not receiving the error message and the application has not been verified, I believe this likely has something to do with the IAM.
I believe I've been able to eliminate managed browsers settings,
cookie settings, and extensions as possible sources of error.
I've also added the users to the GCP project with the Browser role, though
they did not receive invites. What do I need to try next to resolve
this issue?
I cannot provide a minimum reproducible example because this only seems to be confined to a subset of my users' browsers.
I reached out to Google support, but unfortunately this is not covered.
I need to get this application into production relatively soon, so I'm very seriously considering just writing my own Drive microservice and recreating the Picker. I would love to avoid this though.

Azure data factory pagination doesn't work

I am working on a pipeline which executes oAuth2 flow in order to access REST API json data. Once I have the bearer token I am executing a request which returns the following structure:
As you can see, since the response is quite large, there's paging enabled and as part of the response I get a link to the next page. In order to get to that resource I need to also present MS-ContinuationToken in the headers. So, this is how I basically do it in the config of the Copy activity that I use to get the data from the REST endpoint:
and the issue here is that I only get the first 2000 rows and the next page(s) don't seem to be visited at all. Pipeline executes successfully and only the first 2000 items are fetched.
NOTE: continuationToken and links.next.headers.value have the exact same values from the initial response.
Even if you fix the other issue you’ll have an issue with the “next” URL not including “v1”. This is a known issue in the partner center api team. I’ve escalated it pretty high. But they don’t want to break backwards compatibility by changing the “next” URI to include the v1 or to be relative. They are considering other options but I wouldn’t hold your breath.
I would ditch the idea of using data factory and instead write a .NET console app using the partner center SDK
(You might think to paginate manually with loops etc but the Copy activity doesn’t return eg the http headers, so you will need a complex set up to somehow store the data in a data store and be able to look up the last page in order to get the continuation token. I couldn’t figure it out)

How to check data API property when using NuxtJS middleware?

I am building a blog-style app where a user can edit and delete his own posts. When he "deletes" his post, a property in the post object is changed from published: true to published: false . I am not actually removing the post from the database. Now, I sitll want to allow this post to be viewable by the owner of the post if he navigates directly to the post by typing in URL (he may have it bookmarked, too), but I DO NOT want it to be viewable by anyone else, obviously.
I thought maybe page middleware is what I need to use here, but I am unsure how to approach it. Do I somehow check the boolean value of the post's published property in the middleware? If so, how? I know how I can check the user state via something like context.store.state.user.uid , but how would I write the logic to check for the published property? Do I need to do a firestore query?
Here's an example of a blog post's URL schema (contains post id):
mysite.com/users/XmdmZMZkzkRdpZ4oLX5u6MYA9B62/posts/hello-world-title-here
Note: IF there's a better way to approach this rather than using Middleware (maybe I am overthinking this goal) , let me know! Thanks.
Obviously you need to fetch the post somewhere in order to know the published boolean.
A middleware is a good idea if you want to redirects the user going to a post he doesn't have access to (or show the error page).
That requires that you fetch the post from here, and that you have access to the current user from the request.
const validatorMiddleware = async ({ req, error, store }) => {
const post = await axios.get('mypost')
const user = req.user // can come from a previous middleware
if (post.author.id !== user.id) {
error() // Show error page
}
store.commit('addPost', post)
}
export default validatorMiddleware
This is a possibility, then it depends on how you fetch your data etc.