ReferenceError: is not defined - meteor

I'm trying to create a new collection 'profile' when Accounts.onCreateUser is run however I'm getting a ReferenceError: Profile is not defined. I assume it's a load order problem. If I move the schema file into a lib folder it works however I'm trying to use the file structure that is now recommended on the Meteor site.
Can some please let me know what I'm missing. I'm new to import and export to so it might be related to that.
Path: imports/profile/profile.js
import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
SimpleSchema.debug = true;
Profile = new Mongo.Collection("profile");
Profile.allow({
insert: function(userId, doc) {
return !!userId;
},
update: function(userId, doc) {
return !!userId;
},
remove: function(userId, doc) {
return !!userId;
}
});
var Schemas = {};
Schemas.Profile = new SimpleSchema({
userId: {
type: String,
optional: true
},
firstName: {
type: String,
optional: false,
},
familyName: {
type: String,
optional: false
},
});
Profile.attachSchema(Schemas.Profile);
Path: server/userRegistration/createUser.js
Meteor.startup(function () {
console.log('Running server startup code...');
Accounts.onCreateUser(function (options, user) {
if (options.profile && options.profile.roles) {
Roles.setRolesOnUserObj(user, options.profile.roles);
Profile.insert({
userId: user._id,
firstName: options.profile.firstName,
familyName: options.profile.familyName,
});
}
if (options.profile) {
// include the user profile
user.profile = options.profile;
}
return user;
});
});

In your createUser file you need to import the Profile collection. Any files in the imports directory aren't loaded automatically by Meteor, so you need to import them any time you use them. This is why it is working when the file is in the /lib directory but not the /imports directory.
You can import the collection and fix the problem with the following code in your createUser.js file:
import { Profile } from '/imports/profile/profile';
EDIT
I didn't spot that you weren't exporting the collection definition. You need to export the collection definition so that it can be imported elsewhere. Thanks to Michel Floyd for pointing this out. You do that by modifying your code to the following:
export const Profile = new Mongo.Collection( 'profile' );

Related

firebase - get images or files url for storage bucket files

I have to load images uploaded from users into a firebase storage bucket. Each user of my app when create a content can upload some data like video or images and has it's own folder.
At the moment by looking at the structure of the firebase documents I can see that the url is stored inside a field named coverImage and the value is a link to the folder where the user uploads are stored, it's something like this: 0WHq3e2Ki5ObfF5Ztx2/publicPrograms/-MaiINxaLO/coverImage
How I can access to the url of the files? I've tried to follow this guide https://firebase.google.com/docs/storage/web/download-files#download_data_via_url but the ref function that I need to use is already used since I'm loading data from firebase database. Is there another way?
At the moment I have this code
<script>
import { app, db } from '#/firebase/init.js'
import { ref, onValue} from "firebase/database";
//import { getStorage, ref, getDownloadURL } from "firebase/storage";
export default {
name: 'Home',
data() {
return {
firebase: app,
feed: []
}
},
created() {
},
mounted() {
this.initFeed()
},
methods: {
async initFeed() {
const usersData = ref(db, 'Users')
onValue( usersData, (users) => {
//this.feed = snapshot.val()
users.forEach( (user) => {
let profileData = user.val()
if( profileData.hasOwnProperty('publicPrograms') ){
let userPublicPrograms = {
firstName: profileData.name,
lastName: profileData.surname,
profilePic: profileData.propicUrl,
publicPrograms: profileData.publicPrograms
}
this.feed.push(userPublicPrograms)
}
})
})
console.log(this.feed)
},
async initCoverImage(url) {
console.log(url)
return `https://demoapp-ef53f.appspot.com/${url}`
}
}
}
</script>
Any suggestion?

How to clear/delete cache in NextJs?

I have a product page at /products/[slug].js
and I use Incremental Static Generation for a wordpress/graphql site:
export async function getStaticProps(context) {
const {params: { slug }} = context
const {data} = await client.query(({
query: PRODUCT_SLUG,
variables: { slug }
}));
return {
props: {
categoryName: data?.productCategory?.name ?? '',
products: data?.productCategory?.products?.nodes ?? []
},
revalidate: 1
}
}
export async function getStaticPaths () {
const { data } = await client.query({
query: PRODUCT_SLUGS,
})
const pathsData = []
data?.productCategories?.nodes && data?.productCategories?.nodes.map((productCategory) => {
if (!isEmpty(productCategory?.slug)) {
pathsData.push({ params: { slug: productCategory?.slug } })
}
})
return {
paths: pathsData,
fallback: true,
}
}
Everything works as expected except one thing. If I delete a product from wordpress which was previously published, NextJs serves the cached page instead of showing 404 - Not found page, and I think this is how it is supposed to work, meaning that if something isn't rebuilt, show the previous (stale) page.
But how can I completely remove the cache for a specific product which has been deleted and it is not fetched again from the PRODUCT_SLUGS query ?
I have read the fallback options: true, false, blocking but none of them seems to work.
Is there a solution to this, either a next.config.js configuration or another work around ?
So I ran into this same issue, although I am using GraphCMS. So here is what you need to do to fix:
export async function getStaticProps(context) {
const {params: { slug }} = context
const {data} = await client.query(({
query: PRODUCT_SLUG,
variables: { slug }
}));
if (!data) {
return {
notFound: true
}
} else {
return {
props: {
categoryName: data?.productCategory?.name ?? '',
products: data?.productCategory?.products?.nodes ?? []
},
revalidate: 1
}
}
}
You need to return notFound: true in getStaticProps
notFound - An optional boolean value to allow the page to return a 404 status and page.
See this page in the docs https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
Then in getStaticPaths change fallback to fallback: "blocking". If you keep fallback: true it is going to serve the stale page since that built successfully.
I think this is possible starting from next#12.1.x using this feature On-demand Incremental Static Regeneration
https://nextjs.org/blog/next-12-1#on-demand-incremental-static-regeneration-beta
basically you can define an api path in this way
// pages/api/revalidate.js
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
const PRODUCT_SLUGS = req.query.product_slug;
try {
await res.unstable_revalidate(`/products/${PRODUCT_SLUGS}`)
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}
Using this api path you can invalidate the cache for a specific product

GatsbyJS with Firebase - WebpackError: ReferenceError: IDBIndex is not defined

I'm received error with gatsby develop. It's very similar to this one: https://github.com/firebase/firebase-js-sdk/issues/2222, but I'm received error with gatsby develop, not with gatsby build. I did a lot of research but I can't find working solution.
At first I had a problem with gatsby build, like in this post: https://github.com/firebase/firebase-js-sdk/issues/2222, but I resolved it with custom onCreateWebpackConfig(you can find it below).
Stack:
- Gatsby
- Firebase(error probably with that)
- Redux
I'm also delete .cache and node_modules and install everything again, but it didn't work.
Error:
There was an error compiling the html.js component for the development server.
See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html ReferenceError: IDBIndex is not defined
]);
86 |
> 87 | proxyRequestMethods(Index, '_index', IDBIndex, [
| ^
88 | 'get',
89 | 'getKey',
90 | 'getAll',
WebpackError: ReferenceError: IDBIndex is not defined
- idb.mjs:87 Module../node_modules/idb/lib/idb.mjs
node_modules/idb/lib/idb.mjs:87:1
- index.esm.js:1 Module../node_modules/#firebase/installations/dist/index.esm.js
node_modules/#firebase/installations/dist/index.esm.js:1:1
- index.esm.js:1 Module../node_modules/#firebase/analytics/dist/index.esm.js
node_modules/#firebase/analytics/dist/index.esm.js:1:1
- index.esm.js:1 Module../node_modules/firebase/analytics/dist/index.esm.js
node_modules/firebase/analytics/dist/index.esm.js:1:1
- index.ts:1 Module../src/firebase/index.ts
src/firebase/index.ts:1:1
- index.esm.js:32 emit
node_modules/#firebase/analytics/dist/index.esm.js:32:1
My gatsby-node file:
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
if (stage === 'build-html') {
actions.setWebpackConfig({
externals: getConfig().externals.concat(function(context, request, callback) {
const regex = /^#?firebase(\/(.+))?/;
if (regex.test(request)) {
return callback(null, `umd ${request}`);
}
callback();
}),
});
}
};
My firebase dependencies:
"#firebase/firestore-types": "^1.10.1",
"firebase": "^7.13.1",
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.5.0",
"firebase-tools": "^7.16.1",
Firebase index file:
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';
import 'firebase/storage';
import 'firebase/analytics';
const firebaseConfig = {...};
firebase.initializeApp(firebaseConfig);
export const firestore = firebase.firestore();
export const auth = firebase.auth();
export const storage = firebase.storage();
Project repo: https://github.com/olafsulich/Projecty
Post on Github issues: https://github.com/firebase/firebase-js-sdk/issues/2946
Thanks in advance.
The following snippet will only work on build environment because of your condition (stage === 'build-html'):
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
if (stage === 'build-html') {
actions.setWebpackConfig({
externals: getConfig().externals.concat(function(context, request, callback) {
const regex = /^#?firebase(\/(.+))?/;
if (regex.test(request)) {
return callback(null, `umd ${request}`);
}
callback();
}),
});
}
};
Remove it and use it like this:
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
actions.setWebpackConfig({
externals: getConfig().externals.concat(function(context, request, callback) {
const regex = /^#?firebase(\/(.+))?/;
if (regex.test(request)) {
return callback(null, `umd ${request}`);
}
callback();
}),
});
};
Thank's a lot! It's working only on gatbsy develop, but now when I
want to build project, I get an error - TypeError: Cannot read
property 'concat' of undefined. You know how to solve it?
Regarding the new issue, you can follow a workaround in this topic, This is a common error in third-party modules in Gatsby when they try to reach a DOM element (usually window) that is not already defined when the app builds. So, you need to wait until window is defined. You can achieve this in two ways:
Instancing your firebase with a condition like this:
import firebase from '#firebase/app';
import '#firebase/auth';
import '#firebase/firestore';
import '#firebase/functions';
const config = {
... firebase config here
};
let instance;
export default function getFirebase() {
if (typeof window !== 'undefined') {
if (instance) return instance;
instance = firebase.initializeApp(config);
return instance;
}
return null;
}
Note the if (typeof window !== 'undefined') statement
By ignoring firebase module in you webpack configuration like shows their docs. In your gatsby-node.js:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /bad-module/,
use: loaders.null(),
},
],
},
})
}
}
Replace bad module for firebase (or the package/folder name in node_modules). Leave the slashes since test is a regular expression rule
This snippet replaces your previous one that seems to throw an error in concat() function.
For those who wants to try the concat() resolution, this will be helpful too:
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
if (stage === 'build-html') {
actions.setWebpackConfig({
externals: getConfig().externals.concat((context, request, callback) => {
const regex = /^#?firebase(\/(.+))?/
// exclude firebase products from being bundled, so they will be loaded using require() at runtime.
if (regex.test(request)) {
return callback(null, `commonjs ${request}`) // <- use commonjs!
}
callback()
}),
})
}
}
Solved this problem!!
I'm using "gatsby": "^3.10.2", "firebase": "9.0.0-beta.6".
firebase needs to be set externals as commonjs.
gatsby-node.js:
exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
if (stage === 'build-html') {
actions.setWebpackConfig({
externals: getConfig().externals.concat((context, request, callback) => {
const regex = /^#?firebase(\/(.+))?/
// exclude firebase products from being bundled, so they will be loaded using require() at runtime.
if (regex.test(request)) {
return callback(null, `commonjs ${request}`) // <- use commonjs!
}
callback()
}),
})
}
}
Please try this setting.

Getting Cannot read property 'Email' of undefined using meteor and simple-schema

How can I get Email property using simpl-schema? I'm getting undefined message when using calling Email property. Not sure if anything changed because the implementation is according to the docs.
import { Meteor } from "meteor/meteor";
import SimpleSchema from "simpl-schema";
import { Accounts } from "meteor/accounts-base";
Meteor.startup(() => {
// code to run on server at startup
Accounts.validateNewUser(user => {
const email = user.emails[0].address;
try {
new SimpleSchema({
email: {
type: String,
regEx: SimpleSchema.RegEx.Email
}
}).validate({ email });
} catch (e) {
throw new Meteor.Error(400, e.message);
}
return true;
});
});

How to get the user info to the "data" part of the app in vue.js?

Would you happen to know how to set the user to the currentUser?
I am using vuefire and firebase.
The user.uid is returning undefined.
<td v-if="(building['key'] && building['key'].child('ownerId')) == user.uid">
<p >{{building['.key']}} + {{user.uid}}</p>
</td>
this is the rest of my code:
import firebase,{ db, usersRef, buildingsRef } from '../firebase-config';
import { store } from '../store/store';
export default {
firebase() {
// from my understanding this just gives me a quick access to the Refs and a short nomenclature
return {
users: usersRef,
buildings: buildingsRef,
}
},
name: 'buildings',
data () {
return {
user: "",
building: {
name: '',
address: '',
comments: '',
ownerId: '',
},
}
},
I am trying to do it through the store in the beforeCreate hook:
beforeCreate () {
this.$store.dispatch('setUser');
let user = this.$store.getters.getUser;
console.log(user); // this works!!!
this.$set(this.user, 'uid', user.uid )
}
},
If instead I set the user in create hook like this:
created () {
this.$store.dispatch('setUser');
let user = this.$store.getters.getUser;
console.log(user); // this works!!!
this.$set(this.user, 'uid', user.uid )
}
I get this error:
In Vue, the state (aka data properties) is initialized between the beforeCreate and created hooks.
So any change you do to data in beforeCreate is lost.
Change your hook to created
created() { // changed this line
this.$store.dispatch('setUser');
let user = this.$store.getters.getUser;
console.log(user); // this works!!!
this.$set(this.user, 'uid', user.uid)
}

Resources