Is Vercel Caching causing issues? - next.js

For my project i'm using prisma/supabase with next js and then hosting on vercel. Any changes i make to my github automatically generates a new development deployment on vercel. Even though my project is working fine locally, my recent generation resulted in an error which i can only think has something to do with vercels cache.
Half way through the project i added a new field 'slug' to my schema and populated my existing tables with said slug. I then used the slug when generating getStaticProps.
Everything works fine locally but when i generate a new deployment on vercel i get the following error :
Error: Unknown arg `slug` in where.comp.slug for type CompRelationFilter. Did you mean `is`?
Unknown field `slug` for select statement on model Comp. Did you mean `cID`?
at Object.validate (/vercel/path0/node_modules/#prisma/client/runtime/index.js:34758:20)
at PrismaClient._executeRequest (/vercel/path0/node_modules/#prisma/client/runtime/index.js:39752:17)
at consumer (/vercel/path0/node_modules/#prisma/client/runtime/index.js:39693:23)
at /vercel/path0/node_modules/#prisma/client/runtime/index.js:39697:49
at AsyncResource.runInAsyncScope (async_hooks.js:197:9)
at PrismaClient._request (/vercel/path0/node_modules/#prisma/client/runtime/index.js:39697:27)
at request (/vercel/path0/node_modules/#prisma/client/runtime/index.js:39802:77)
at _callback (/vercel/path0/node_modules/#prisma/client/runtime/index.js:40010:14)
at PrismaPromise.then (/vercel/path0/node_modules/#prisma/client/runtime/index.js:40017:23)
I created a new migration, synced it to my database, comfirmed its there on both prisma studio and database directly. So my only guess is it has something to do with vercel's cache, have they cached my database somewhere or something in node modules thats attributing to this error?
This is my retrieval code that works perfectly for other pages:
const data = await prisma.event.findMany({
where: {
sTime: {
gte: numericToDate(numericDate(today), [0,0]), //provided date from 0 hours
},
comp: {
slug: compPre
}},
orderBy: {
sTime: 'asc',
},
include: {
Eventor: {
select: {
title: true,
type:true,
eID: true,
imgUrl: true
}, // Return all fields
},
ch: {
select: {
title: true,
chID: true,
imgUrl: true
}, // Return all fields
},
sport: {
select: {
title: true,
sID: true
}, // Return all fields
},
comp: {
select: {
title: true,
slug: true,
cID: true,
imgUrl:true
}, // Return all fields
}},
})
Thanks for any help

Fixed it by including:
"vercel-build": "prisma generate && prisma migrate deploy && next build",
in scripts in package.json

Related

500 Internal Server Error fetch()'ing data with Next.js app deployed on Netlify (works locally)

I'm building a toy app with Next.js 13 (with the new app/ directory). My app works fine locally, but generates a 500 Internal Server Error when deployed to Netlify.
Here's the route that generates the error
app/team/[id]/page.jsx
import Link from "next/link";
async function getEmployee() {
const res = await fetch(
'https://dynamic-routes--dundermifflininc.netlify.app/.netlify/functions/team?id=1',
{ cache: 'no-store' }
);
return await res.json();
}
export default async function Employee() {
const employee = await getEmployee();
return (
<div>
<h1>{ employee.name }</h1>
<h3>{ employee.title }</h3>
</div>
);
}
I am confident that the error is happening with fetch(), because if I replace fetch() with hard-coded data, the app works properly. Additionally, the logs for my netlify function indicate that the endpoint isn't even being hit by the fetch() call.
The Netlify function is defined like this
netlify/functions/team.js
exports.handler = async function (event, context) {
const employees = [
{ id: 1, name: "Michael Scott", title: "Regional manager" },
{ id: 2, name: "Jim Halpert", title: "Salesman" },
{ id: 3, name: "Pam Beesly", title: "Receptionist" },
{ id: 4, name: "Dwight Schrute", title: "Assistant to the regional manager" },
];
var data;
if (event.queryStringParameters.hasOwnProperty("id")) {
const id = parseInt(event.queryStringParameters.id);
data = employees[id - 1];
} else {
data = employees;
}
return {
statusCode: 200,
body: JSON.stringify(data),
headers: {
'access-control-allow-origin': '*',
'content-type': 'application/json'
},
};
};
You can test the endpoint for yourself here.
I couldn't reproduce this on a demo site, but checking the logs for your example it's giving the error: "Error: Page changed from static to dynamic at runtime /team/1, see more here https://nextjs.org/docs/messages/app-static-to-dynamic-error
I'm not sure why it's trying to statically render it when you have no-store set, but you might want to try following the instruction in the linked doc, and exporting export const dynamic = 'force-dynamic' in the page.
A good way to track this down is to run netlify serve locally, using the latest version of the Netlify CLI. This is a new option that runs the site in a production-like environment

How to prevent direct access to pages url in nextjs when used rewrites?

My problem is : I have pages/blog.js file in my project. I did localized urls like down below in the next.config.js file.
i18n:{
locales:["tr","en"],
defaultLocale:"tr"
},
async rewrites(){
return [
{
"source":"/tr/makaleler",
"destination":"/blog",
"locale":false
},
{
"source":"/en/articles",
"destination":"/blog",
"locale":false
}
]
}
It works. But problems is ; I can still access with this localhost:3000/blog. I want to make it only accessible with localhost:3000/makaleler or localhost:3000/en/articles.
Is there any way to achieve this? I have read "nextjs" documentation bu couldn't find anything useful.
Essentially what you want is not possible, The reason is if you restrict access to localhost:3000/blog by any means, then your rewrites will stop working as well.
What you probably need is redirects from localhost:3000/blog to the desired locale for your users. You can leverage Accept-Language header for example:
async redirects() {
return [
{
source: '/blog',
has: [
{
type: 'header',
key: 'accept-language',
// header starts with tr
value: 'tr(.*)',
},
],
destination: '/tr/makaleler',
permanent: false,
},
{
source: '/blog',
has: [
{
type: 'header',
key: 'accept-language',
// header does not start with tr
value: '((?!tr$).*)',
},
],
destination: '/en/articles',
permanent: false,
},
]
}
You should use Next.js Middleware in version 12.2 if you want to implement complex redirect logic based on language (or anything). You can find a quick tutorial by Vercel in Youtube here: https://youtu.be/j7rPSS9Ovsw?t=296

Is there a way to dynamically assign a country to defaultCountry in firebase phone authentication for web?

I am trying to use firebase phone authentication for web and vuejs. I want to detect the country of the user and assign the detected country as the defaultCountry in the firebaseui config.
signInOptions: [
firebase.auth.EmailAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
recaptchaParameters: {
type: 'image',
size: 'invisible',
badge: 'bottomleft'
},
defaultCountry: `'${this.countryCode}'`
}
]
Below is the method I used to successfully get the country and assign to a variable in data ()
created() {
this.getDefaultCountry()
},
I even tried
defaultCountry: this.countryCode
If I hardcode a countryCode ('US', 'NZ', ... ), it works.
Thank you
If this.getDefaultCountry() is synchronous (i.e. doesn't require any database lookups, promises, etc), you should be able to use the following code, where defaultCountry is swapped out for a getter instead of a static value:
signInOptions: [
firebase.auth.EmailAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
recaptchaParameters: {
type: 'image',
size: 'invisible',
badge: 'bottomleft'
},
get defaultCountry() {
// contents of getDefaultCountry here
}
}
]
If your this.getDefaultCountry() is asynchronous, you will instead have to show some form of loading screen while you get the value, build signInOptions, give it to your FirebaseUI config and then finally render it.

Nextjs and workbox integration

Requirement: I am trying to use service worker and cache static files so as to have a benefit to reduce HTTP requests and make the site performance better. 
Down the lane I would switch to offline, caching images, api's etc.
I have seen the plugins:
https://github.com/hanford/next-offline and
https://www.npmjs.com/package/next-pwa
It seems to work. Although I was trying to find out if there were examples of (nextjs + workbox).
Next js do have an example for https://github.com/vercel/next.js/tree/canary/examples/with-next-offline. But I would like just using workbox for this.
Anyone got any working examples? Even a basic one would do.
Currently am not using a custom server. Just using the inbuilt builder of nextjs (https://nextjs.org/docs/getting-started#manual-setup)
I figured out an answer on my own:
Reference: https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.generateSW
I have done runtime caching for my app here and added the workbox file into the base file:
// Use the window load event to keep the page load performant
useEffect(() => {
window.addEventListener("load", () => {
const serviceWorkerScope = `/${country}/workbox-worker.js`
navigator.serviceWorker
.register(serviceWorkerScope)
.then(() => {
logger.info(`Service worker registered at ${serviceWorkerScope}`)
})
.catch(error => {
logger.error("Error in serviceWorker registration: ", error)
})
})
})
I have added comments,
// File to generate the service worker.
require("dotenv").config()
const workboxBuild = require("workbox-build")
const { COUNTRY: country, NODE_ENV } = process.env
const urlPattern = new RegExp(`/${country}\/static|_next\/.*/`)
// https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.generateSW
const buildSW = () => {
return workboxBuild.generateSW({
swDest: "public/workbox-worker.js",
clientsClaim: true,
mode: NODE_ENV,
skipWaiting: true,
sourcemap: false,
runtimeCaching: [
{
urlPattern: urlPattern,
// Apply a cache-first strategy.
handler: "CacheFirst",
options: {
cacheName: "Static files caching",
expiration: {
maxEntries: 50,
maxAgeSeconds: 15 * 60, // 15minutes
},
},
},
],
})
}
buildSW()

Can't Figure Out How to Use Gridsome-Plugin-Firestore

I am trying to use the gridsome-plugin-firestore plugin (https://gridsome.org/plugins/gridsome-source-firestore). I want to use that plugin to connect to a simple firestore database collection called news. News has a number of documents with various fields:
content
published_date
summary
author
title
etc.
Does anyone know how am I supposed to set up the gridsome.config file to access this collection using the gridsome-plugin-firestore plugin?. I cannot figure it out from the instructions given.
The Gridsome docs are a little clearer than npm version, but you need to generate a Firebase Admin SDK private key and download the whole file to your Gridsome app and import it into gridsome.config.js as a module, name it whatever you want for the options > credentials: require field as below.
First, you'll need the Firestore plugin
$ yarn add gridsome-source-firestore
Then in gridsome.config.js
const { db } = require('gridsome-source-firestore')
module.exports = {
plugins: [
{
use: 'gridsome-source-firestore',
options: {
credentials: require('./my-project-firebase-adminsdk-qw2123.json'), //
Replace with your credentials file you downloaded.
debug: true, // Default false, should be true to enable live data updates
ignoreImages: false, // Default false
imageDirectory: 'fg_images', // Default /fg_images
collections: [
{
ref: (db) => {
return db.collection('news')
},
slug: (doc, slugify) => {
return `/news/${slugify(doc.data.title)}`
},
children: [
{
ref: (db, parentDoc) => {
return parentDoc.ref.collection('posts')
},
slug: (doc, slugify) => {
return `/${slugify(doc.data.title)}`
},
}
]
}
]
}
}
]
}
You might have to change "posts" to "content" depending on your DB structure and alter the corresponding page queries to suit, there are some examples and other useful setup info in this Gridsome Firestore starter on Github https://github.com/u12206050/gridsome-firestore-starter.git

Resources