title: Can't deploy cloud functions
body: <p>I have tried to deploy cloud functions for more than a week, but I always get an error in the log and the functions don't deploy.</p>
  <p>I receive the following error in the log:</p>
  <pre><code>{&quot;@type&quot;:&quot;type.googleapis.com/google.cloud.audit.AuditLog&quot;,&quot;status&quot;:{&quot;code&quot;:3,&quot;message&quot;:&quot;Build failed: npm ERR! cipm can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.\nnpm ERR! \nnpm ERR! \nnpm ERR! Missing: nodemailer@^6.6.0\nnpm ERR! \n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR!     /builder/home/.npm/_logs/2021-05-13T16_38_49_151Z-debug.log; Error ID: beaf8772&quot;}
  </code></pre>
  <p>This is the code of my function:</p>
  <pre><code>const functions = require(&quot;firebase-functions&quot;);
  const nodemailer = require(&quot;nodemailer&quot;);
  
  const admin = require(&quot;firebase-admin&quot;);
  
  const serviceAccount = require(&quot;admin_sdk.json&quot;);
  
  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: &quot;https://enjoylearning-a3ce3.firebaseio.com&quot;,
  });
  
  admin.firestore().settings({timestampsInSnapshots: true});
  
  const db = admin.firestore();
  
  // For Gmail, enable these:
  // 1. https://www.google.com/settings/security/lesssecureapps
  // 2. https://accounts.google.com/DisplayUnlockCaptcha
  // For other types of transports such as Sendgrid see https://nodemailer.com/transports/
  // auth.languageCode = 'ar';
  const gmailEmail = XXXX;
  const gmailPassword = XXXX;
  const mailTransport = nodemailer.createTransport({
    service: &quot;gmail&quot;,
    auth: {
      user: gmailEmail,
      pass: gmailPassword,
    },
  });
  
  // Your company name to include in the emails
  // TODO: Change this to your app or company name to customize the email sent.
  const APP_NAME = &quot;EduCup&quot;;
  
  // [START sendWelcomeEmail]
  /**
   * Sends a welcome email to new user.
   */
  // [START onCreateTrigger]
  /* exports.sendWelcomeEmail = functions.auth.user().onCreate((user) =&gt; {
  // [END onCreateTrigger]
    // [START eventAttributes]
    const email = user.email; // The email of the user.
    const displayName = user.displayName; // The display name of the user.
  
    return sendWelcomeEmail(email, displayName);
  }); */
  
  exports.sendWelcomeEmail = functions.firestore
      .document(&quot;users/{user}&quot;)
      .onCreate(async (snap, context) =&gt; {
        const email = snap.data().userEmail; // The email of the user.
        const displayName = snap.data().userName; // The display name of the user.
        const uid = snap.data().userId;
  
        return sendWelcomeEmail(email, displayName, uid);
      });
  
  // [END sendWelcomeEmail]
  
  // [START onCreateTrigger]
  
  
  
  exports.addPoints = functions.firestore
      .document(&quot;users/{user}&quot;)
      .onCreate(async (snap, context) =&gt; {
        const invitingFriendId = snap.data().invitingFriendId;
        const newUserEmail = snap.data().userEmail;
        const invitingFriendRef = db.collection(&quot;users&quot;).doc(invitingFriendId);
        let friendEmail;
  
        const transaction = db.runTransaction((t) =&gt; {
          return t.get(invitingFriendRef).then((doc) =&gt; {
            // Add to the chain count
            const userData = doc.data();
            const newPoints = userData.points + 50;
            // let newCompetitionPoints = userData.competitionPoints + 50;
            let newInviteesNo = userData.inviteesNo + 1;
            // console.log(&quot;competition points is : &quot; + newCompetitionPoints);
  
            /*   if(isNaN(newCompetitionPoints)||
            newCompetitionPoints == undefined ||
             newCompetitionPoints == null){
                newCompetitionPoints = Number(50);
                console.log(&quot;if called , newCompetition points is : &quot; +
                newCompetitionPoints);
              } */
  
  
            if (isNaN(newInviteesNo)|| newInviteesNo == undefined ||
               newInviteesNo == null) {
              newInviteesNo = Number(1);
              console.log(&quot;if called , newInviteesNo is : &quot; + newInviteesNo);
            }
  
            friendEmail = doc.data().userEmail;
            t.update(invitingFriendRef, {inviteesNo: newInviteesNo,
              points: newPoints});
  
            console.log(&quot;friend email is : &quot; + friendEmail +
               &quot; , new userEmail is : &quot; + newUserEmail);
          });
        }).then((result) =&gt; {
          console.log(&quot;Transaction success!&quot;);
          return sendNewFriendAddedEmail(friendEmail, newUserEmail);
        }).catch((err) =&gt; {
          console.log(&quot;Transaction failure:&quot;, err);
          return true;
        });
      });
  
  
  /*
  exports.addSecondChallengerPoints = functions.firestore.document
  (`challenges/{challengeId}`).onUpdate(async (snap, context) =&gt; {
  
  const player1Score = snap.after.data().player1score;
  const player1Uid = snap.after.data().player1Uid;
  const player2Score = snap.after.data().player2score;
  const challengeId = snap.after.data().challengeId;
  const score1Added = snap.after.data().score1Added;
  
  
  const drawChallengePoints = 1;
  const winChallengepoints = 5;
  
  const opponentRef = db.collection('users').doc(player1Uid);
  const challengeRef = db.collection('challenges').doc(challengeId);
  
      let transaction = db.runTransaction(t =&gt; {
    return t.get(opponentRef).then(doc =&gt; {
  
  const noOfWins = doc.data().noOfWins;
  const noOfDraws = doc.data().noOfDraws;
  const noOfLoses = doc.data().noOfLoses;
  const totalChallengesNo = doc.data().totalChallengesNo;
  const oldPoints = doc.data().points;
  
  console.log(&quot;player1Score : &quot; + player1Score + &quot; , player2Score : &quot;
   + player2Score
    + &quot; old points : &quot; + oldPoints + &quot; , totalChallengesNo : &quot;
    + totalChallengesNo);
  
        if(player1Score == player2Score){
                const newPoints = oldPoints + drawChallengePoints;
  
                t.update(challengeRef, {&quot;score1Added&quot;: true});
                t.update(opponentRef, {&quot;points&quot;: newPoints});
                t.update(opponentRef,
                 {&quot;totalChallengesNo&quot;: totalChallengesNo + 1});
                t.update(opponentRef, {&quot;noOfDraws&quot;: noOfDraws + 1});
        } else if(player1Score &gt; player2Score){
                const newPoints = oldPoints + winChallengepoints;
  
                t.update(challengeRef, {&quot;score1Added&quot;: true});
                t.update(opponentRef, {&quot;points&quot;: newPoints});
                t.update(opponentRef, {&quot;totalChallengesNo&quot;:
                totalChallengesNo + 1});
                t.update(opponentRef, {&quot;noOfWins&quot;: noOfWins + 1});
        } else {
                t.update(challengeRef, {&quot;score1Added&quot;: true});
                t.update(opponentRef, {&quot;totalChallengesNo&quot;:
                totalChallengesNo + 1});
                t.update(opponentRef, {&quot;noOfLoses&quot;: noOfLoses + 1});
        }
    });
  }).then(result =&gt; {
    console.log('Transaction success!');
  }).catch(err =&gt; {
    console.log('Transaction failure:', err);
  });
  
  return true;
  });
  */
  
  // [START sendByeEmail]
  /**
   * Send an account deleted email confirmation to users
   *  who delete their accounts.
   */
  /* TODO :remove this comment to add goodbye email
  // [START onDeleteTrigger]
  exports.sendByeEmail = functions.auth.user()
  .onDelete((user) =&gt; {
  // [END onDeleteTrigger]
    const email = user.email;
    const displayName = user.displayName;
  
    return sendGoodbyeEmail(email, displayName);
  });
  // [END sendByeEmail]
  
  
  */
  
  // Sends a welcome email to the given user.
  function sendWelcomeEmail(email, displayName, uid) {
    const mailOptions = {
      from: `${APP_NAME} &lt;noreply@firebase.com&gt;`,
      to: email,
    };
  
    // The user subscribed to the newsletter.
    mailOptions.subject = &quot;welcome to our app! &quot;;
    const strtText = &quot;Welcome to our app! We hope you enjoy it.&quot;;
    const pageLink = &quot;To know the latest news about the app and the latest competitions please join our facebook group : \n\n https://www.facebook.com/groups/434661403874384/&quot;;
    mailOptions.text = strtText + &quot;\n\n&quot; + pageLink;
    // TODO : add new line instead of space
    return mailTransport.sendMail(mailOptions).then(() =&gt; {
      return console.log(&quot;New welcome email sent to:&quot;, email);
    });
  }
  
  // Sends a welcome email to the given user.
  function sendNewFriendAddedEmail(friendEmail, newUserEmail) {
    const mailOptions = {
      from: `${APP_NAME} &lt;noreply@firebase.com&gt;`,
      to: friendEmail,
    };
  
    console.log(&quot;sendNewFriendAddedEmail called&quot;);
  
    // The user subscribed to the newsletter.
    mailOptions.subject = &quot;You won 50 points!&quot;;
    const strtText=&quot;We are glad to inform you that your friend whose email is \&quot;&quot;+
     newUserEmail +&quot;\&quot; has registered to the app using your code and you&quot;+
     &quot; have got 50 points in the app.&quot;+
      &quot; \n\nInvite more friends to get more points in our app.&quot;;
    mailOptions.text = strtText;
  
    /* return mailTransport.sendMail(mailOptions).then(() =&gt; {
      return console.log('New points email sent to:', friendEmail);
    }) */
  
    return mailTransport.sendMail(mailOptions, function(error, info) {
      if (error) {
        return console.log(error);
      }
      else {
        return console.log(&quot;Email sent: &quot; + info.response);
      }
    });
  }
  </code></pre>
  <p>I tried different solutions but still, I have the error mentioned above and I still can't deploy my functions</p>