'cloudinary error: must supply api-key - /node_modules/cloudinary/lib/utils.js:982
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 %>
Solution 1:[1]
The 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 committing 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.com/documentation/node_integration.
Solution 2:[2]
The reason can be your js file where you would have not included require('dotenv').config();
Try adding this and then run your code.
Solution 3:[3]
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
Solution 4:[4]
The dotenv must be required up top where you are using your process.env.API_KEY
:
require("dotenv").config();
Solution 5:[5]
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
});
Solution 6:[6]
use this
const dotenv = require('dotenv'); dotenv.config();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | adiga |
Solution 2 | Manoj |
Solution 3 | Aditi Madan |
Solution 4 | unixb0y |
Solution 5 | Chukwunazaekpere |
Solution 6 | Abhishek Dulat |