I am trying to deploy this repo: https://github.com/DataStax-Examples/astra-tik-tok with Vercel instead of Netlify.
I refactored vanilla React into Next.js, but in the Home.js file I don't understand how to migrate this over to Vercel's equivalent:
//fetch all the tik-tok posts to your feed
const fetchData = async () => {
const results = await axios.get('/.netlify/functions/posts')
console.log(results.data)
setUsers(results.data)
}
Any ideas?
The equivalent in Next.js are API routes, which get deployed as serverless functions in Vercel. They must be created under the /pages/api folder.
You need to slightly refactor the functions to work with Next.js. For example, your add.js function would look like the following as an API route.
// /pages/api/add.js
export default function handler(req, res) {
const users = await getCollection();
try {
const user = await users.create(id, event.body);
res.status(200).json(user);
} catch (e) {
console.error(e);
res.status(500).json({ error: JSON.stringify(e) })
}
};
You would then call the API route from the client-side code by pointing to /api/add.
await axios.get('/api/add')
Related
I'm trying to create a new document when a user signs up for my app.
However, 'exports' is returning "Uncaught (in promise) ReferenceError: exports is not defined".
The code below is handling the function. I do also have an onAuthStateChanged function that switches some logged-in/out elements, although I don't think that could be stopping exports from being defined.
import { createUserWithEmailAndPassword, onAuthStateChanged,
signInWithEmailAndPassword } from "firebase/auth";
import { db, auth } from "./firebase";
import { collection, doc, setDoc, addDoc } from "firebase/firestore";
const signUpForm = document.querySelector('#signup-form');
if (signUpForm) {
signUpForm.addEventListener('submit', (e) => {
e.preventDefault();
//get user info
const email = signUpForm['signup-email'].value;
const password = signUpForm['signup-password'].value;
createUserWithEmailAndPassword(auth, email, password).then((cred) => {
const overlay = document.getElementById('overlay');
overlay.classList.add('hidden');
overlayP.classList.remove('hidden');
signUpForm.reset();
exports.createUserDoc = functions.auth.user().onCreate((user) => {
return admin.firestore().collection("users").doc(user.uid).setDoc({
email: user.email,
uid: user.uid,
})
});
// document.getElementById("signUpErr").innerHTML = "";
})
// .catch(err => {
// document.getElementById("signUpErr").innerHTML = err.message;
// });
});
};
I have initialized firebase and installed express.js within my index.js file but am I missing something to make sure this parameter is defined? I'm using Vite as a package bundler and node.js.
I'm new to coding and firebase, any advice would be massively appreciated.
I managed to solve this issue by taking a few days to read the documentation and understand what is going on with Cloud functions. The benefit of having a cloud function is that you can create triggers to your database that is away from your client-side code, improving security.
I was trying to call the cloud function within my app.js file and not within the firestore functions index.js file created when initializing firebase. Here you import through CommonJS Modules (CJS) the required SDK, in my case it was functions and admin.
Now my cloud functions live within index.js in /Functions folder separate from my app files.
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
I also had to change the .setDoc() function to .set() as this was a Type error. I also added a userDelete function to delete users' documents in firestore.
exports.createUserDoc = functions.auth.user().onCreate(user => {
// Your new auth record will have the uid and email on it because
// you used email as the way to create the auth record
return admin.firestore().collection("users").doc(user.uid).set({
email: user.email,
bookmarked: []
})
});
exports.userDeleted = functions.auth.user().onDelete(user => {
const doc = admin.firestore().collection("users").doc(user.uid);
return doc.delete();
});
I would also like to note that setting up the firestore emulator has been very useful in this process and I'm sure will help me develop and test the other functions I need to create my app.
I'm building on Next.js app and when I install / import Plaiceholder (for generating placeholder images), I get the following error: Module not found: Can't resolve 'child_process'
Node v14.18.0
Next.js v11.1.2
Plaiceholder v2.2.0
Sharp v0.29.2
I understand this error message to mean that webpack5 is trying to bundle node packages that aren't available to the client. But I'm not clear why it is doing this. I haven't customized any of the webpack configs, and I can't find any mention of this issue in the Plaiceholder docs. How do I fix it?
NOTE: I want the base64 data URL to get created during the build, so that it available as soon as the page loads (not fetched asynchronously at run time).
Here's my next.config.js
module.exports = {
reactStrictMode: true,
};
My package.json only has scripts, dependencies, and devDependencies (nothing to change module resolution)
In case it's relevant, here's a simplified example using Plaiceholder:
import Image from "next/image";
import { getPlaiceholder } from "plaiceholder";
import React, { useState } from "react";
...
const { base64 } = await getPlaiceholder(imgUrl);
...
return (<Image
src={imgUrl}
placeholder="blur"
blurDataURL={base64}
/>);
It seems like plaiceholder is not suitable for client-side rendering. I believe that package is for the Node.js environment. That's why you get this error when you try to render your component on the client side.
To solve this problem, you need to move import { getPlaiceholder } from 'plaiceholder' to the NextJS API section. Then you can call that API with your URL data in the body. Then get the base64.
/api/getBase64.js
import { getPlaiceholder } from "plaiceholder";
export default async (req, res) => {
const { body } = req;
const { url } = body;
const { base64 } = getPlaiceholder(url);
res.status(200).send(base64);
};
/component.js
import Image from "next/image";
import React, { useState, useEffect } from "react";
const [base64, setBase64] = useState()
useEffect(() => {
(async () => {
const _base64 = await fetch.post('/api/getBase64', {url: imgUrl}); // wrote for demonstration
setBase64(_base64);
})()
})
return (<Image
src={imgUrl}
placeholder="blur"
blurDataURL={base64}
/>);
I know blurDataURL will be undefined until you fetch the data but this is the way how you can use plaiceholder library to manage your images. It should be imported only for the NodeJS environment. If you do not like this approach, you can try to find another library that also works for the browser environment (client)
UPDATED according to the comment:
If you want to generate this base64 at build time, you can use getStaticProps in the pages that use this Image component. NextJS is smart enough to understand which libraries are used in the client-side or server-side. So you can do this:
import { getPlaiceholder } from "plaiceholder"; // place it at the root of file. This will not be bundled inside of client-side code
export async function getStaticProps(context) {
const { base64 } = await getPlaiceholder(imgUrl);
return {
props: { base64 }, // will be passed to the page component as props
}
}
This way, by using getStaticProps, the page will be created at build time. You can get the base64 prop inside of the page that uses the image component and pass that prop to blurDataURL. Also, you can use this approach with getServerSideProps too.
This is from NextJS website:
Note: You can import modules in top-level scope for use in
getServerSideProps. Imports used in getServerSideProps will not be
bundled for the client-side.
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
It's necessary to Install plugin for Next Js dependency and configure next config based on Plaiceholder Docs for using getPlaiceholder() function in getStaticProps like the answer by #oakar.
npm i #plaiceholder/next
const { withPlaiceholder } = require("#plaiceholder/next");
module.exports = withPlaiceholder({
// your Next.js config
});
I have tried to integrate firebase with Nuxt Js and i am getting this error
As per documentation first I have installed firebase with help of "npm install firebase" and then i have installed "npm install #nuxtjs/firebase" and third i have integrated my firebase config in modules in nuxt.config.js
so whats the solution to solve the above error?
Thanks in advance
It depends on which version of #nuxtjs/firebase you are using, because this package #nuxtjs/firebase is not compatible with firebase version 9+ supporting tree-shaking.
So you need to downgrade you package to firebase version 8 and prior.
For more information, please check the authors github issues.
If you are using the new Modular SDK v9.0.1 you might get the above error as it does not use firebase. namespace now,
Try using getApps() instead of firebase.apps.
import { initializeApp, getApps } from "firebase/app"
import { getFirestore } from "firebase/firestore"
import { getAuth } from "firebase/auth"
const firebaseConfig = {...}
if (!getApps().length) {
//....
}
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)
const auth = getAuth(app) export {db, auth}
I banged my head against this problem for a while - I was trying to use the Realtime Database in a dynamic page and getting the same error. I finally went back to this issue on the firebase module repo. Basically I had to do two things:
use the async asyncData method instead of just defining data properties; and
use both the app and params variables.
So instead of this:
export default {
data: () => ({
items: []
)},
async fetch ({ params }) {
const ref = this.$fire.database.ref(`foo/${params.slug}`)
const data = (await ref.once('value')).val()
this.items = data
}
}
I had to do this:
export default {
async asyncData ({ app, params }) {
const ref = app.$fire.database.ref(`foo/${params.slug}`)
const data = (await ref.once('value')).val()
return { items: data }
}
}
I am building an app using react native, I use firebase as my database. Everything was working fine. I started running the app on my device through Xcode. It worked but now I get this warning on my device and simulator which prevents me from getting data from firebase database. the warning is
"Possible Unhandled Promise Rejection (id: 20):
TypeError: _util.base64.tI is not a function. (In '_util.base64.tI(t, !1)', '_util.base64.tI' is undefined)"
I don't know where did this (_util.base64) come from. I guess the problem has to do with this code part (the promise) as when I remove this part it works fine but unable to get data without it. can anyone help?
useEffect(() => {
db.collection("Appointments")
.orderBy("Timing", "desc")
.limit(2)
.get()
.then((querySnapshot) => {
const list = [];
querySnapshot.forEach((doc) => {
const { Speciality, Date, TimeSlot } = doc.data();
list.push({
id: doc.id,
Speciality,
Date,
TimeSlot,
});
});
setAppointments(list);
})
.catch((error) => {
alert(error.message);
console.log(error);
});
}, []);
This is the warning that shows up
Those are my dependencies
What I did to solve it was:
run expo install firebase
Create a config.js file where I put my Firebase credentials:
import * as firebase from 'firebase';
// Initialize Firebase
var firebaseConfig = {
//Your Firebase credentials
};
var app = firebase.initializeApp(firebaseConfig);
export const db = app;
And import that file wherever I need it
import { db } from '../config';
//Here's where I call firestore (You can also do this in the config file)
import 'firebase/firestore';
db.firestore().
collection('your_collection').get().then(
//The stuff you want to do
);
At least, now it works for me.
In this link you can see the oficial expo with firebase documentation
I'm working on a project using meteor + react as front-and-back end.
For front-end UI, I am using element-react (https://eleme.github.io/element-react/#/en-US/quick-start) which is really cool and awesome. However when I tried to import element-react into my project (as instructed in the quick start of element-react homepage), meteor failed to compile static files and returned "Uncaught Error: Cannot find module './assets/error.svg''" which is the file do exist and has correct relative path.
Is there something missing or in meteor we simply can not use "require('./assets/error.svg')" to load a svg image?
According to this post in Meteor's forum.
You can use something like Meteor methods and the Assets API to get most any data from your server though. Something like
/server/main.js
Meteor.methods({
'svg.get'(data) {
return Assets.getText(data.path)
}
})
and
/client/main.js
const getSVG = async (path) => {
return await new Promise((resolve, reject) => {
Meteor.call('svg.get', { path }, (err, res) => {
if (err) reject('Something went wrong')
resolve(res)
})
})
}
const SVG = await getSVG('some/path/relative/to/private/file.svg')