<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Farhan Farooq</title>
    <description>The latest articles on DEV Community by Farhan Farooq (@itsmefarhan).</description>
    <link>https://dev.to/itsmefarhan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F484498%2Fef2dac4b-6e5d-426a-a972-435281b5e368.jpeg</url>
      <title>DEV Community: Farhan Farooq</title>
      <link>https://dev.to/itsmefarhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itsmefarhan"/>
    <language>en</language>
    <item>
      <title>Build classified ads project with React and Firebase</title>
      <dc:creator>Farhan Farooq</dc:creator>
      <pubDate>Fri, 07 Apr 2023 16:04:49 +0000</pubDate>
      <link>https://dev.to/itsmefarhan/build-classified-ads-project-with-react-and-firebase-19p5</link>
      <guid>https://dev.to/itsmefarhan/build-classified-ads-project-with-react-and-firebase-19p5</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this course we will build a classified advertisement website where users will be able to buy and sell products.&lt;/p&gt;

&lt;p&gt;The tech stack will be React, Bootstrap and Firebase. We will work with a few features provided by firebase such as authentication, firestore as database and firebase storage to store images. We will use the latest firebase version 9 which is based on modular approach.&lt;/p&gt;

&lt;p&gt;We will use many functions provided by firebase for authentication, firestore and storage which are usually used in any medium scale website.&lt;/p&gt;

&lt;p&gt;Once we are done with our project, we will then deploy it on vercel and also we will see how to secure firestore and storage with firebase security rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Authentication - account creation, login, logout, forgot password and reset password&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticated users will be able to upload, change or remove their profile photo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seller can publish ad specifying the details of the product they want to sell&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User can filter the ads by category or sort by price&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User can view the ad on landing page as well as on seller's profile page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticated user can mark any ad as favorite or remove from his favorite ads list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticated user can reach out to seller via phone or chat system within the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seller can delete own ad&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seller can mark the ad as sold&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Basic knowledge of Reactjs is required for this course which means you should know what is useEffect / useState / props / context etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/build-classified-ads-project-with-react-and-firebase/?referralCode=125E0D804CB85EB6E204" rel="noopener noreferrer"&gt;Watch the demo&lt;/a&gt; to know what we will be building in this project and if this is something you would like to build then please get enrolled.&lt;/p&gt;

&lt;p&gt;$9.99 disounted coupon: &lt;strong&gt;APRIL-2023-B&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>firebase</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Cloudinary Files / Images CRUD operations with Nodejs, Express, Multer</title>
      <dc:creator>Farhan Farooq</dc:creator>
      <pubDate>Wed, 07 Oct 2020 15:30:45 +0000</pubDate>
      <link>https://dev.to/itsmefarhan/cloudinary-files-images-crud-operations-with-nodejs-express-multer-2147</link>
      <guid>https://dev.to/itsmefarhan/cloudinary-files-images-crud-operations-with-nodejs-express-multer-2147</guid>
      <description>&lt;p&gt;In this article we will upload, retrieve, update and delete images from Cloudinary. For that, we will use nodejs, express, multer, cloudinary and also mongoDB as our database.&lt;/p&gt;

&lt;p&gt;If you prefer watching video tutorial then watch this:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LWB1s6P0wgE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;or you may continue reading. First of all create project directory, open this directory in code editor. Now we will initialize &lt;strong&gt;package.json&lt;/strong&gt; file. Open your terminal and run&lt;br&gt;
&lt;code&gt;npm init -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After that we will install a few dependencies.&lt;br&gt;
&lt;code&gt;npm install express mongoose cloudinary multer dotenv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Optionally, I will also install nodemon as dev dependency to constantly watch server.&lt;br&gt;
&lt;code&gt;npm install -D nodemon&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now within &lt;strong&gt;package.json&lt;/strong&gt; inside "scripts", add&lt;br&gt;
&lt;code&gt;"server": "nodemon index"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we will setup basic express server. Create &lt;strong&gt;index.js&lt;/strong&gt; file and paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
dotenv.config(); 

// Connect DB
mongoose
  .connect(process.env.MONGO_URI, {
    useCreateIndex: true,
    useNewUrlParser: true,
    useFindAndModify: false,
    useUnifiedTopology: true,
  })
  .then(() =&amp;gt; console.log("mongoDB is connected"))
  .catch((err) =&amp;gt; console.log(err)); 

// Middleware
app.use(express.json());

app.listen(5000, () =&amp;gt; console.log("Server is running"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create .env file and add&lt;br&gt;
&lt;code&gt;MONGO_URI=path-to-your-mongodb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open terminal and type &lt;code&gt;npm run server&lt;/code&gt; to see if everything is working fine.&lt;/p&gt;

&lt;p&gt;Lets create a folder at root level &lt;strong&gt;models&lt;/strong&gt; and inside models create a file &lt;strong&gt;user.js&lt;/strong&gt; and paste the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
  name: {
    type: String,
  },
  avatar: {
    type: String,
  },
  cloudinary_id: {
    type: String,
  },
});
module.exports = mongoose.model("User", userSchema);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have defined three fields, name, avatar and cloudinary_id. We will need cloudinary_id when we will send put / delete request later.&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://cloudinary.com" rel="noopener noreferrer"&gt;Cloudinary website&lt;/a&gt; and register / login. You will be redirected to your dashboard where under &lt;strong&gt;Account Details&lt;/strong&gt; you will find your &lt;strong&gt;Cloud Name&lt;/strong&gt;, &lt;strong&gt;API Key&lt;/strong&gt; and &lt;strong&gt;API Secret&lt;/strong&gt;. Copy their values and inside &lt;strong&gt;.env&lt;/strong&gt; file create 3 variables to store those values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLOUD_NAME=YOUR-CLOUD-NAME
API_KEY=YOUR-API-KEY
API_SECRET=YOUR-API-SECRET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a folder at root level &lt;strong&gt;utils&lt;/strong&gt; and create 2 files inside this folder, &lt;strong&gt;cloudinary.js&lt;/strong&gt; and &lt;strong&gt;multer.js&lt;/strong&gt;. Here we will configure cloudinary and multer. Inside &lt;strong&gt;cloudinary.js&lt;/strong&gt; paste the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const cloudinary = require("cloudinary").v2;
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
}); 
module.exports = cloudinary;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;strong&gt;multer.js&lt;/strong&gt; paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const multer = require("multer");
const path = require("path"); 
// Multer config
module.exports = multer({
  storage: multer.diskStorage({}),
  fileFilter: (req, file, cb) =&amp;gt; {
    let ext = path.extname(file.originalname);
      if (ext !== ".jpg" &amp;amp;&amp;amp; ext !== ".jpeg" &amp;amp;&amp;amp; ext !== ".png") {
      cb(new Error("File type is not supported"), false);
      return;
    }
    cb(null, true);
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have required multer and nodejs core module path. We required path to extract file extension in order to filter files we want to allow.&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;index.js&lt;/strong&gt; and before listening to server, add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Route
app.use('/user', require('./routes/user'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a folder at root level &lt;strong&gt;routes&lt;/strong&gt; and inside routes create file &lt;strong&gt;user.js&lt;/strong&gt;. Now we will send a post request to upload image to cloudinary. Inside &lt;strong&gt;user.js&lt;/strong&gt; file paste the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = require("express").Router();
const cloudinary = require("../utils/cloudinary");
const upload = require("../utils/multer");
const User = require("../model/user"); 
router.post("/", upload.single("image"), async (req, res) =&amp;gt; {
  try {
    // Upload image to cloudinary
    const result = await cloudinary.uploader.upload(req.file.path);
     // Create new user
    let user = new User({
      name: req.body.name,
      avatar: result.secure_url,
      cloudinary_id: result.public_id,
    });
    // Save user
    await user.save();
    res.json(user);
  } catch (err) {
    console.log(err);
  }}); 
 module.exports = router;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we required express router, from utils folder cloudinary and multer and User model. We are uploading single image so right after router url, we have specified upload.single('image').&lt;/p&gt;

&lt;p&gt;We used &lt;strong&gt;cloudinary.uploader.upload&lt;/strong&gt; and pass the file path to upload method to get the image. We stored the response we got back from cloudinary into result variable. It will be an object and we will use two properties &lt;strong&gt;secure_url&lt;/strong&gt; and &lt;strong&gt;public_id&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After the image is uploaded, we created new instance of user. name will be provided in req.body, avatar and cloudinary_id values will be result.secure_url and result.public_id respectively.&lt;/p&gt;

&lt;p&gt;Now go to &lt;strong&gt;postman&lt;/strong&gt; make a POST request to &lt;a href="http://localhost:5000/user" rel="noopener noreferrer"&gt;http://localhost:5000/user&lt;/a&gt; provide &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;image&lt;/strong&gt; in form-data and hit SEND. Navigate to "Media Library" in your cloudinary account you will find the image you just uploaded.&lt;/p&gt;

&lt;p&gt;Let's make a GET request, go to &lt;strong&gt;user.js&lt;/strong&gt; and paste the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.get("/", async (req, res) =&amp;gt; {
  try {
    let user = await User.find();
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DELETE request&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.delete("/:id", async (req, res) =&amp;gt; {
  try {
    // Find user by id
    let user = await User.findById(req.params.id);
    // Delete image from cloudinary
    await cloudinary.uploader.destroy(user.cloudinary_id);
    // Delete user from db
    await user.remove();
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First find user by id, after that we are deleting file from cloudinary. &lt;strong&gt;destroy&lt;/strong&gt; method takes &lt;strong&gt;public_id&lt;/strong&gt; as argument, we have stored public_id as cloudinary_id into our DB&lt;/p&gt;

&lt;p&gt;PUT request&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.put("/:id", upload.single("image"), async (req, res) =&amp;gt; {
  try {
    let user = await User.findById(req.params.id);
    // Delete image from cloudinary
    await cloudinary.uploader.destroy(user.cloudinary_id);
    // Upload image to cloudinary
    const result = await cloudinary.uploader.upload(req.file.path);
    const data = {
      name: req.body.name || user.name,
      avatar: result.secure_url || user.avatar,
      cloudinary_id: result.public_id || user.cloudinary_id,
    };
    user = await User.findByIdAndUpdate(req.params.id, data, {
 new: true
 });
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First find user by id, then delete the existing image from cloudinary. After that upload the new image to cloudinary and update the data with the updated secure_url and public_id into our database as avatar and cloudinary_id&lt;/p&gt;

&lt;p&gt;So thats how we can perform CRUD operations on cloudinary with nodejs multer and cloudinary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/itsmefarhan/nodejs-cloudinary-crud-operations" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>cloudinary</category>
    </item>
  </channel>
</rss>
