I am using cloudinary to upload photos on my webpage. I have added a new function to the webpage ( facebook login) and now the cloudinary throw an error when I try to upload a photo like before.
"/home/ubuntu/workspace/YelpCamp/node_modules/cloudinary/lib/utils.js:982 throw "Must supply api_key"; ^ Must supply api_key"
The API_KEY, API_SECRET and the CLOUD_NAME are saved in a .env file, and these are correct.
var express = require("express");
var router = express.Router();
var Campground = require("../models/campground");
var middleware = require('../middleware') ; //because of the index.js default name
var geocoder = require('geocoder');
///////////////////////////////////////
// MULTER
var multer = require('multer');
var storage = multer.diskStorage({
filename: function(req, file, callback) {
callback(null, Date.now() + file.originalname);
}
});
var imageFilter = function (req, file, cb) {
// accept image files only
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/i)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
};
var upload = multer({ storage: storage, fileFilter: imageFilter});
///////////////////////////////////////
//CLOUDINARY
var cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_KEY,
api_secret: process.env.CLOUD_SECRET
});
router.post('/', middleware.isLoggedIn, upload.single('image'), function(req, res) {
console.log(req.user);
//GEOCODER
geocoder.geocode(req.body.location, function (err, data) {
//CLOUDINARY UPLOAD
cloudinary.uploader.upload(req.file.path, function(result) {
var image = {
path: result.secure_url,
id: result.public_id
};
var name = req.body.name;
var price = req.body.price;
var description = req.body.description;
if(req.user.facebook.username) {
var username = req.user.facebook.username;
} else {
username = req.user.local.username;
}
var author = {
id: req.user._id,
username: username
};
if(!data.results[0]) {
var lat = 90;
var lng = 0;
var location = "North Pole";
} else {
lat = data.results[0].geometry.location.lat;
lng = data.results[0].geometry.location.lng;
location = data.results[0].formatted_address;
}
var newCampground = {name: name, price: price, image: image, description: description, author: author, location: location, lat: lat, lng: lng};
//create
Campground.create(newCampground, function(err, result) {
if(err) {
console.log(err);
} else {
console.log(result);
res.redirect('/campgrounds');
}
});
});
});
});
<% include ../partials/header %>
<div class="row">
<h1 style="text-align: center;">Create a New CampGround</h1>
<div style='width: 30%; margin: 30px auto;'>
<form action='/campgrounds' method='POST' enctype="multipart/form-data">
<div class='form-group'>
<label for="name">Name</label>
<input class="form-control" id="name" type='text' name='name' placeholder='Name'>
</div>
<div class='form-group'>
<label for="price">Price</label>
<input class="form-control" id="price" type='number' name='price' placeholder='price' min="0.01" step="0.01">
</div>
<div class='form-group'>
<label for="image">Image</label>
<input type="file" id="image" name="image" accept="image/*" required>
</div>
<div class='form-group'>
<label for="description">Description</label>
<input class="form-control" id="description" type='text' name='description' placeholder='Write description'>
</div>
<div class="form-group">
<label for="location">Location</label>
<input class="form-control" type="text" name="location" id="location" placeholder="Yosemite National Park, CA">
</div>
<div class='form-group'>
<button class="btn btn-lg btn-default btn-primary btn-block">Submit!</button>
</div>
</form>
<a href="/campgrounds"> Go Back </a>
</div>
</div>
<% include ../partials/footer %>
I am using cloudinary to upload photos on my webpage. I have added a new function to the webpage ( facebook login) and now the cloudinary throw an error when I try to upload a photo like before.
"/home/ubuntu/workspace/YelpCamp/node_modules/cloudinary/lib/utils.js:982 throw "Must supply api_key"; ^ Must supply api_key"
The API_KEY, API_SECRET and the CLOUD_NAME are saved in a .env file, and these are correct.
var express = require("express");
var router = express.Router();
var Campground = require("../models/campground");
var middleware = require('../middleware') ; //because of the index.js default name
var geocoder = require('geocoder');
///////////////////////////////////////
// MULTER
var multer = require('multer');
var storage = multer.diskStorage({
filename: function(req, file, callback) {
callback(null, Date.now() + file.originalname);
}
});
var imageFilter = function (req, file, cb) {
// accept image files only
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/i)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
};
var upload = multer({ storage: storage, fileFilter: imageFilter});
///////////////////////////////////////
//CLOUDINARY
var cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_KEY,
api_secret: process.env.CLOUD_SECRET
});
router.post('/', middleware.isLoggedIn, upload.single('image'), function(req, res) {
console.log(req.user);
//GEOCODER
geocoder.geocode(req.body.location, function (err, data) {
//CLOUDINARY UPLOAD
cloudinary.uploader.upload(req.file.path, function(result) {
var image = {
path: result.secure_url,
id: result.public_id
};
var name = req.body.name;
var price = req.body.price;
var description = req.body.description;
if(req.user.facebook.username) {
var username = req.user.facebook.username;
} else {
username = req.user.local.username;
}
var author = {
id: req.user._id,
username: username
};
if(!data.results[0]) {
var lat = 90;
var lng = 0;
var location = "North Pole";
} else {
lat = data.results[0].geometry.location.lat;
lng = data.results[0].geometry.location.lng;
location = data.results[0].formatted_address;
}
var newCampground = {name: name, price: price, image: image, description: description, author: author, location: location, lat: lat, lng: lng};
//create
Campground.create(newCampground, function(err, result) {
if(err) {
console.log(err);
} else {
console.log(result);
res.redirect('/campgrounds');
}
});
});
});
});
<% include ../partials/header %>
<div class="row">
<h1 style="text-align: center;">Create a New CampGround</h1>
<div style='width: 30%; margin: 30px auto;'>
<form action='/campgrounds' method='POST' enctype="multipart/form-data">
<div class='form-group'>
<label for="name">Name</label>
<input class="form-control" id="name" type='text' name='name' placeholder='Name'>
</div>
<div class='form-group'>
<label for="price">Price</label>
<input class="form-control" id="price" type='number' name='price' placeholder='price' min="0.01" step="0.01">
</div>
<div class='form-group'>
<label for="image">Image</label>
<input type="file" id="image" name="image" accept="image/*" required>
</div>
<div class='form-group'>
<label for="description">Description</label>
<input class="form-control" id="description" type='text' name='description' placeholder='Write description'>
</div>
<div class="form-group">
<label for="location">Location</label>
<input class="form-control" type="text" name="location" id="location" placeholder="Yosemite National Park, CA">
</div>
<div class='form-group'>
<button class="btn btn-lg btn-default btn-primary btn-block">Submit!</button>
</div>
</form>
<a href="/campgrounds"> Go Back </a>
</div>
</div>
<% include ../partials/footer %>
Share
Improve this question
asked Dec 25, 2017 at 15:20
Gábor KereszthegyiGábor Kereszthegyi
411 gold badge1 silver badge2 bronze badges
2
-
"API_KEY, API_SECRET and the CLOUD_NAME are saved in a .env file" did you mean
CLOUD_KEY
&CLOUD_SECRET
or is that a typo? – palaѕн Commented Dec 25, 2017 at 15:23 - Yes, sorry I mean CLOUD_KEY & CLOUD_SECRET and CLOUD_NAME are saved in a .env file. – Gábor Kereszthegyi Commented Dec 25, 2017 at 19:19
8 Answers
Reset to default 6The cloudinary config values must be in strings otherwise they won't work. Configure your code either of these ways in your cloudinary segment:
1a: CloudinaryConfig.js:
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_KEY,
api_secret: process.env.CLOUD_SECRET
});
1b: .env
CLOUDINARY_CLOUD_NAME='sample'
CLOUDINARY_API_KEY='874837483274837'
CLOUDINARY_API_SECRET='a676b67565c6767a6767d6767f676fe1'
2: Putting your cloudinary-supplied values directly into the code:
cloudinary.config({
cloud_name: 'sample',
api_key: '874837483274837',
api_secret: 'a676b67565c6767a6767d6767f676fe1'
});
NOTE: Ensure that you don't expose your config values for security reasons. If you're mitting code to a public repo like github, use .gitignore to leave out whatever file where you store your secret info.
Checkout the cloudinary docs for more reference: https://cloudinary./documentation/node_integration.
The reason can be your js file where you would have not included require('dotenv').config();
Try adding this and then run your code.
The dotenv must be required up top where you are using your process.env.API_KEY
:
require("dotenv").config();
for mon js files put :
const dotenv = require('dotenv');
dotenv.config();
for mjs files put:
import * as dotenv from "dotenv";
dotenv.config();
in the same js/mjs file that you use:
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_KEY,
api_secret: process.env.CLOUD_SECRET
});
I was facing a similar problem and I tried all the above answers but none of them worked. I tried printing the secrets and it was showing undefined. Even though I had the .env file setup.
After some digging I found out that my cloudinary.config({}) function was getting executed even before the .env file is processed in my index.js file.
The solution which I implemented is adding the .env config in the cloudinary configuration file again.
for mon js
const dotenv = require('dotenv');
dotenv.config({
path: "your_env_file_path"
});
for module js
import dotenv from "dotenv";
dotenv.config({
path: "your_env_file_path"
});
Can you try putting the API key directly in your code and see if that works. You could also add a print statement and see what response you get for API key
If you're using a NodeJS server-side function to upload, ensure you've installed the dotenv package;
yarn add dotenv
Thereafter, put the cloudinary variables in a '.env' file. From the file (controller) where you're to make the upload, you must point to dotenv, to that file, relative to where your package.json file is sitting. Here's an instance for me, trying to make an upload from 'CompanyControllers.ts'
import dotenv from "dotenv";
dotenv.config({path: "./backend/src/settings/controllers/CompanyControllers.ts"});
So, if I do;
console.log("\n\t Cloud name: ", process.env.CLOUDINARY_UPLOAD_CLOUD_NAME)
.....my cloudinary cloud name is logged
const cloudinaryResponse = await cloudinary.v2.uploader.upload(filePath, {
cloud_name: process.env.CLOUDINARY_UPLOAD_CLOUD_NAME,
api_secret: process.env.CLOUDINARY_UPLOAD_API_SECRET,
upload_preset: process.env.CLOUDINARY_UPLOAD_PRESET_NAME,
api_key: process.env.CLOUDINARY_UPLOAD_API_KEY,
resource_type: "image",
secure: true
});
use this
const dotenv = require('dotenv'); dotenv.config();