Inconsistent getServerSideProps behaviour using NextJS in vercel - redirect

I have the following setup
/template. Loads a page that shows all the templates owned by the current user.
/template/new. Loads a page that allows the user to create a template and save it.
/api/save-template. Receives the frontend call made from /template/new and handles storing it on the db.
With those routes, a typical use case is the following:
User ends up somehow (irrelevant) on /template/new.
User creates a template and hit "save". A spiner shows up while saving happens.
Template payload is sent via POST HTTP request to /api/save-template.
/api/save-template route handles the saving successfully and responds with a status 200.
The spinner finishes and the user is redirected to /template, where the newly created template should hopefully show up.
The problem here is on point 5, where in some scenarios, the newly created template doesn't show up. Here's what happens on different scenarios. The app could be running either using next dev, next build && next start, or deployed on vercel. The database could either be hosted locally on docker, or on the cloud using supabase.
db \ app
next dev
next build...
vercel
docker
✅
✅
haven't tried
supabase
✅
✅
❌
One thing to keep in mind, which might be related to the reason this is not working, is that the redirection is made on the frontend using router.push('/template').
I'm also checking on the client side what templates are available when reaching point 5. I've confirmed this is not a db delay issue because the templates are found by the client. For those checks I'm using the following code:
useEffect(() => {
const checkSupabase = async () => {
const templatesResponse = await supabase
.from<Template[]>('Template')
.select('*')
const templates = templatesResponse.data
console.log('templates found from useEffect')
console.log(templates)
}
checkSupabase()
}, [])
And the last thing I want to point out is that the logs I get from vercel make me think the getServerSideProps is not called. I'm logging templates found from getServerSideProps to see what's available on that function. I see the log before creating the template (time 21:31:24:00), and then the /api/save-template being hit (time 21:31:47:11), but I don't see the second request to /template after the redirect. The logs –note the order is newest on the top– are:
21:31:47:11 - [POST] /api/save-template
21:31:24:00 - [GET] /template
templates found from getServerSideProps
[]
Questions
How is it that I don't see a second log for [GET] /template or the templates found from getServerSideProps log? Is it not being fired?
If getServerSideProps is not fired, how come this works when the app is running locally?
Is there a consistent solution for this use case? I guess it must be quite common to want to see recently created data.
Thanks!

Related

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.

Keycloak URL fragments do not disappear when logged in

Keycloak inserts session_state, state and code in url fragment params.. sometimes after successful login these remain on the url...
Or, when alternate routes are clicked in the app, these appear again.
Unnecessarily exposing the internals of keycloak params to users.
Is there some solution to not have these appear or delete them?
e.g. http://localhost:3000/home/#state=e625140e-c4f9-4500-858e-32c80e89f8a9&session_state=445229c3-d7eb-46e9-bfba-3339253dd17e&code=af0abde4-a60d-4f34-a101-8db5c76546b9.445229c3-d7eb-46e9-bfba-3339253dd17e.59915134-a59b-4ffb-878a-d02e7e84f2dd
Update:
with more tests narrowed down the issue to occur when
anything on the keycloak instance is touched. e.g. keycloak.token
any function call of keycloak is invoked... then after that these params get added and removed for every url route thereafter...
e.g. await keycloak.updateToken()
Keycloak Sever and js lib Version : 9.0.2
It is not a Keycloak issue. That's how used login flow works (maybe you need different flow, which will be more suitable for your use case). Your app code (used OIDC/OAuth library) should "clean" URL fragments. Cleaning can be: exchange code for the token (in this particular case), remove URL fragments, clean browser history, etc.

Aqueduct template db_and_auth not rendering login form

I am working on setting up OAuth 2.0 for aqueduct and want to start with a working example. The template db_and_auth is suppose to serve this purpose.
I have followed the readme instructions and connected my database and updated the migration. also I have registered OAuth 2.0 clients in the application database as the readme describes.
The template comes with a route in the channel.dart
router
.route("/auth/form")
.link(() => AuthRedirectController(authServer, delegate: this));
The AuthRedirectController is set up to render a html page (web/login.html) which is part of the template.
However every time I send a get request to this route it returns with a 400 error saying Error
unsupported_response_type in the browser. Additionally in the readme file it only shows testing auth end points using curl. Why would this template include a rendered login page without mention of it in the readme? Any help with this would be much appreciated.
The login form will only be rendered when you pass the correct response_type like so:
http://localhost:8888/auth/form?response_type=token

Is there a smart possibility to get API results without sending requests every second? [VueJS | Vuetify]

So I made a website to show which services on my server are running and which are offline.
The site is an Vuetify App running in a docker container. My services are monitored via UptimeRobot.
Currently I use:
created: function () {
this.interval = setInterval(() => this.getStatuses(), 1000);
},
To trigger my API request function every second to update the status of my services.
But is there some smarter possibility to only update on change and not request every second to see if something happened?
Like I send one request to get the status and then receive a message when something changed? I hope you can understand, whats my problem. It's hard to decribe.
Yes you can by firing an event. for example:
in your app.js
window.Fire = new Vue();
For example here you create a user then you want to update table after creating a new user, Follow these steps:
createUser(){
// FireUpdate is your fire name, you can give it any name you want!
// Call this after you post something to specific route.
Fire.$emit('FireUpadte');
}
Then you will load new users using this approach:
created(){
// Load new Users after created.
Fire.$on('FireUpadte', () => { this.createUser(); });
}
For more information check this video: https://www.youtube.com/watch?v=DHuTkJzH2jI&list=PLB4AdipoHpxaHDLIaMdtro1eXnQtl_UvE&index=20
What you're looking for are websockets. You establish a websocket connection and it stays open, allowing the server to notify the web app when something changes.
You can run your own socket.io server on a Node.js backend or use a service like Pusher.com (very cheap, free tier is pretty big).
I highly recommend going the Pusher.com route, they also have great tutorials ; )
https://pusher.com

FlowRouter Reload Doesn't Route

I'm using FlowRouter. If I start on the homepage everything works well. I can work through the routes (change the pages) without problem. However, if I hit refresh in the browser, I get a series of errors. My url looks like this:
/story/586d536e34821281735b53a4
The ID is being returned in console under the following method:
Tracker.nonreactive(function(){
I think the subscription is being completed, so I'm a little confused as to why reloading a url is different than loading from the home page.
What am I not understanding here?
Reloading a url will make a HTTP request to server to get all the application source. Whereas navigating to a route from another one does not make any HTTP requests to get the application source because they are already available (they were loaded from the previous route), in this case the router will just get the appropriate content and render on the page. This is normal behaviour for Meteor apps and all other single-page apps
The error you encounter is because your data is not yet available on client, to fix it you could simple use a placeholder if the value is undefined.