Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase - Error: There was an error deploying functions

Ok, y'all I am in a pickle here. I've been working on all my firebase functions for a few days and thought I was making really good progress until I went to deploy after several days of testing with the firebase server and postman... It won't deploy T_T

The error I am getting in the terminal when I use firebase --debug deploy is:

2022-01-25T17:23:50.575Z] Total Function Deployment time: 57866
[2022-01-25T17:23:50.575Z] 1 Functions Deployed
[2022-01-25T17:23:50.575Z] 1 Functions Errored
[2022-01-25T17:23:50.575Z] 0 Function Deployments Aborted
[2022-01-25T17:23:50.575Z] Average Function Deployment time: 57864

Functions deploy had errors with the following functions:
        api(us-central1)
[2022-01-25T17:23:50.713Z] Missing URI for HTTPS function in printTriggerUrls. This shouldn't happen
in  functions: cleaning up build files... 
[2022-01-25T17:23:50.719Z] >>> [apiv2][query] DELETE https://artifactregistry.googleapis.com/v1beta2/projects/lxai-mentor-matching/locations/us-central1/repositories/gcf-artifacts/packages/api [none]
[2022-01-25T17:23:50.722Z] >>> [apiv2][query] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/tags/list [none]
[2022-01-25T17:23:50.918Z] <<< [apiv2][status] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/tags/list 200
[2022-01-25T17:23:50.918Z] <<< [apiv2][body] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/tags/list {"child":["5fbdb989-6e6d-42bc-9a25-3073c3098d76"],"manifest":{},"name":"lxai-mentor-matching/gcf/us-central1","tags":[]}
[2022-01-25T17:23:50.918Z] >>> [apiv2][query] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/tags/list [none]
[2022-01-25T17:23:50.931Z] <<< [apiv2][status] DELETE https://artifactregistry.googleapis.com/v1beta2/projects/lxai-mentor-matching/locations/us-central1/repositories/gcf-artifacts/packages/api 404
[2022-01-25T17:23:50.933Z] <<< [apiv2][body] DELETE https://artifactregistry.googleapis.com/v1beta2/projects/lxai-mentor-matching/locations/us-central1/repositories/gcf-artifacts/packages/api {"error":{"code":404,"message":"Repository does not exist: \"projects/lxai-mentor-matching/locations/us-central1/repositories/gcf-artifacts\"","status":"NOT_FOUND"}}
[2022-01-25T17:23:51.061Z] <<< [apiv2][status] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/tags/list 200
[2022-01-25T17:23:51.063Z] <<< [apiv2][body] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/tags/list {"child":["cache"],"manifest":{"sha256:efea96d0dec08db58767f472cc16a3c17c277e41d844a61bbdb745e49c7cd8e6":{"imageSizeBytes":"421918451","layerId":"","mediaType":"application/vnd.docker.distribution.manifest.v2+json","tag":["api_version-15","latest"],"timeCreatedMs":"315532801000","timeUploadedMs":"1643131418106"}},"name":"lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76","tags":["api_version-15","latest"]}
[2022-01-25T17:23:51.064Z] >>> [apiv2][query] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/tags/list [none]
[2022-01-25T17:23:51.069Z] >>> [apiv2][query] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/api_version-15 [none]
[2022-01-25T17:23:51.230Z] <<< [apiv2][status] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/latest 202
[2022-01-25T17:23:51.231Z] <<< [apiv2][body] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/latest {"errors":[]}
[2022-01-25T17:23:51.250Z] <<< [apiv2][status] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/tags/list 200
[2022-01-25T17:23:51.250Z] <<< [apiv2][body] GET https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/tags/list {"child":[],"manifest":{"sha256:75f8940b6524c90f2b653b387e0cab4a9ae9f3dbebb2e5f4dfb03fc3345ead6f":{"imageSizeBytes":"13412478","layerId":"","mediaType":"application/vnd.docker.distribution.manifest.v2+json","tag":["latest"],"timeCreatedMs":"315532801000","timeUploadedMs":"1643131418618"}},"name":"lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache","tags":["latest"]}
[2022-01-25T17:23:51.251Z] >>> [apiv2][query] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/latest [none]
[2022-01-25T17:23:51.256Z] <<< [apiv2][status] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/api_version-15 202
[2022-01-25T17:23:51.256Z] <<< [apiv2][body] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/api_version-15 {"errors":[]}
[2022-01-25T17:23:51.257Z] >>> [apiv2][query] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/sha256:efea96d0dec08db58767f472cc16a3c17c277e41d844a61bbdb745e49c7cd8e6 [none]
[2022-01-25T17:23:51.386Z] <<< [apiv2][status] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/latest 202
[2022-01-25T17:23:51.386Z] <<< [apiv2][body] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/latest {"errors":[]}
[2022-01-25T17:23:51.387Z] >>> [apiv2][query] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/sha256:75f8940b6524c90f2b653b387e0cab4a9ae9f3dbebb2e5f4dfb03fc3345ead6f [none]
[2022-01-25T17:23:51.683Z] <<< [apiv2][status] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/sha256:efea96d0dec08db58767f472cc16a3c17c277e41d844a61bbdb745e49c7cd8e6 202
[2022-01-25T17:23:51.683Z] <<< [apiv2][body] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/manifests/sha256:efea96d0dec08db58767f472cc16a3c17c277e41d844a61bbdb745e49c7cd8e6 {"errors":[]}
[2022-01-25T17:23:51.728Z] <<< [apiv2][status] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/sha256:75f8940b6524c90f2b653b387e0cab4a9ae9f3dbebb2e5f4dfb03fc3345ead6f 202
[2022-01-25T17:23:51.729Z] <<< [apiv2][body] DELETE https://us.gcr.io/v2/lxai-mentor-matching/gcf/us-central1/5fbdb989-6e6d-42bc-9a25-3073c3098d76/cache/manifests/sha256:75f8940b6524c90f2b653b387e0cab4a9ae9f3dbebb2e5f4dfb03fc3345ead6f {"errors":[]}
[2022-01-25T17:23:51.852Z] Error: Failed to update function api in region us-central1
    at /Users/tmac/.nvm/versions/node/v17.3.0/lib/node_modules/firebase-tools/lib/deploy/functions/release/fabricator.js:38:11
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Fabricator.updateV1Function (/Users/tmac/.nvm/versions/node/v17.3.0/lib/node_modules/firebase-tools/lib/deploy/functions/release/fabricator.js:255:32)
    at async Fabricator.updateEndpoint (/Users/tmac/.nvm/versions/node/v17.3.0/lib/node_modules/firebase-tools/lib/deploy/functions/release/fabricator.js:136:13)
    at async handle (/Users/tmac/.nvm/versions/node/v17.3.0/lib/node_modules/firebase-tools/lib/deploy/functions/release/fabricator.js:75:17)

Error: There was an error deploying functions

Having read a few other posts here I am super confused as to what the error is and where I can hunt it down. Everything has been working locally with firebase serve. When I check the log files I get this:


11:23:52.550 AM
api
{"@type":"type.googleapis.com/google.cloud.audit.AuditLog","status":
{"code":3,"message":"Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation."},"authenticationInfo":{"principalEmail":"[email protected]"},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","resourceName":"projects/lxai-mentor-matching/locations/us-central1/functions/api"}

One post here was about space in a file name, but that's not my issue, another was about package.json so I'm posting mine here but not sure what I am looking for. Any idea on how to dig deeper or what to look for so I can get deploy working again?

package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "16"
  },
  "main": "index.js",
  "dependencies": {
    "firebase-admin": "^9.8.0",
    "firebase-functions": "^3.14.1"
  },
  "devDependencies": {
    "firebase-functions-test": "^0.2.0"
  },
  "private": true
}

index.js

const functions = require('firebase-functions');
const app = require('express')();

const { postOneScream } = require('./handlers/screams');
const {
  signup,
  login,
  uploadImage,
  addUserDetails,
} = require('./handlers/users');
const { addMentee, getMentees, updateMentee } = require('./handlers/mentees');
const { addMentor, getMentors, updateMentor } = require('./handlers/mentors');

const { FBAuth } = require('./util/fbAuth');

//**POST ROUTES**
// Scream routes - Testing post functionality for social media feed posts
app.post('/screams', FBAuth, postOneScream);

// Signup route
app.post('/signup', signup);

// Sign In route
app.post('/login', login);

// Upload an image route
app.post('/users/image', FBAuth, uploadImage);

// Add details to user profile
app.post('/users', FBAuth, addUserDetails);

// Mentee Signup / Update
app.post('/mentees', FBAuth, addMentee);
app.post('/mentees', FBAuth, updateMentee);
// Mentor Signup
app.post('/mentors', FBAuth, addMentor);
app.post('/mentors', FBAuth, updateMentor);

//**GET ROUTES**

// Get all mentees
app.get('/mentees', getMentees);
// Get all mentors
app.get('/mentors', getMentors);

//**Export API**
// export api allows us to use express for our function formating
exports.api = functions.https.onRequest(app);

users.js

const { admin, db } = require('../util/admin');
const firebase = require('firebase');

const config = require('../util/config');
firebase.initializeApp(config);

const {
  validateSignupData,
  validateLoginData,
  reduceUserDetails,
} = require('../util/validators');

exports.signup = async (req, res) => {
  const newUser = {
    email: req.body.email,
    password: req.body.password,
    confirmPassword: req.body.confirmPassword,
    handle: req.body.handle,
  };

  // Validating the fields for user signup
  const { valid, errors } = validateSignupData(newUser);

  if (!valid) return res.status(400).json(errors);
  const noImg = 'no-img.png';

  const userDoc = await db.doc(`/users/${newUser.handle}`).get();
  if (userDoc.exists) {
    return res.status(400).json({ handle: 'This handle already taken' });
  } else {
    // Create user
    let userId;
    await firebase
      .auth()
      .createUserWithEmailAndPassword(newUser.email, newUser.password)
      .then((data) => {
        userId = data.user.uid;
        return data.user.getIdToken();
      })
      .then((userToken) => {
        // Add User to Users Collection
        const uToken = userToken;
        const userCredentials = {
          handle: newUser.handle,
          email: newUser.email,
          createdAt: new Date().toISOString(),
          imgURL: `https://firebasetorage.googleapis.com/v0/b/${config.storageBucket}/o/${noImg}?alt=media`,
          userId,
        };
        db.doc(`/users/${newUser.handle}`).set(userCredentials);
        return userToken;
      })
      .then((userToken) => {
        return res
          .status(201)
          .json({ message: 'User created successfully', token: userToken });
      })
      .catch((err) => {
        console.error(err);
        if (err.code === 'auth/email-already-in-use') {
          return res.status(400).json({ email: 'Email is already in use' });
        } else {
          return res.status(500).json({ error: err.code });
        }
      });
  }
};

exports.login = (req, res) => {
  const user = {
    email: req.body.email,
    password: req.body.password,
  };

  // Validating the fields for user login
  const { valid, errors } = validateLoginData(user);

  if (!valid) return res.status(400).json(errors);

  // Log the user in and get a token
  firebase
    .auth()
    .signInWithEmailAndPassword(user.email, user.password)
    .then((data) => {
      return data.user.getIdToken();
    })
    .then((token) => {
      res.json({ token });
    })
    .catch((err) => {
      console.error(err);
      if (err.code === 'auth/wrong-password') {
        return res.status(403).json({ general: 'Wrong credentials' });
      } else {
        return res.status(500).json({ error: err.code });
      }
    });
};

// Upload an image for user profile page
exports.uploadImage = (req, res) => {
  const BusBoy = require('busboy');
  const path = require('path');
  const os = require('os');
  const fs = require('fs');

  const busboy = BusBoy({ headers: req.headers });

  let imageFileName;
  let imageToBeUploaded = {};

  busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
    if (
      mimetype !== 'image/jpeg' &&
      mimetype !== 'image/png' &&
      mimetype !== 'image/jpg'
    ) {
      return res
        .status(400)
        .json({ error: 'Wrong file type, please use JPG/JPEG/PNG' });
    }
    const fileName = filename.filename + '';
    const imageExtention = fileName.split('.')[fileName.split('.').length - 1];
    // Not sure why we need to change file name but this is the tutorial recommendation
    imageFileName = `${Math.round(
      Math.random() * 10000000000,
    )}.${imageExtention}`;
    console.log(imageFileName);
    const filePath = path.join(os.tmpdir(), imageFileName);
    imageToBeUploaded = { filePath, mimetype };
    file.pipe(fs.createWriteStream(filePath));
  });
  busboy.on('finish', () => {
    admin
      .storage()
      .bucket()
      .upload(imageToBeUploaded.filePath, {
        resumable: false,
        metadata: {
          metadata: {
            contentType: imageToBeUploaded.mimetype,
          },
        },
      })
      .then(() => {
        const imgURL = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imageFileName}?alt=media`;
        return db.doc(`/users/${req.user.handle}`).update({ imgURL });
      })
      .then(() => {
        return res.json({ message: 'Image uploaded successfully' });
      })
      .catch((err) => {
        console.error(err);
        return res.status(500).json({ error: err.code });
      });
  });
  busboy.end(req.rawBody);
};

// Add user details to user collection in db / user profile in react
exports.addUserDetails = (req, res) => {
  let userDetails = reduceUserDetails(req.body);

  db.doc(`/users/${req.user.handle}`)
    .update(userDetails)
    .then(() => {
      return res.status(200).json({ message: 'Details added successfully' });
    })
    .catch((err) => {
      console.error(err);
      return res.status(500).json({ error: err.code });
    });
};

screams.js

const { db } = require('../util/admin');

exports.postOneScream = (req, res) => {
  const newScream = {
    body: req.body.body,
    userHandle: req.user.handle,
    createdAt: new Date().toISOString(),
  };

  db.collection('screams')
    .add(newScream)
    .then((doc) => {
      res.json({ message: `document ${doc.id} created successfully` });
    })
    .catch((err) => {
      res.status(500).json({ error: 'something went wrong' });
      console.error(err);
    });
};

mentees.js

const { db } = require('../util/admin');


const { reduceMenteeDetails } = require('../util/validators');


// Add a mentee to the mentees collection
exports.addMentee = (req, res) => {
    
    let menteeDetails = reduceMenteeDetails(req);

    db.doc(`/mentees/${req.user.handle}`).set(menteeDetails)
    .then(() => {
        return res.status(200).json({ message: 'Details added successfully' });
    }).catch(err => {
        console.error(err);
        return res.status(500).json({ error: err.code });
    })
}

// Get all Mentees from the mentee collection
exports.getMentees = (req, res) => {
    db.collection('mentees').get()
    .then((data) => {
        let mentees = [];
        data.forEach((doc) => {
            mentees.push(doc.data())
        });
        return res.json(mentees);
    })
    .catch(err => {
        console.error(err);
        return res.status(500).json({ error: err.code })
    })
}

// Update an existing mentee
exports.updateMentee = (req, res) => {
    let menteeDetails = reduceMenteeDetails(req);

    db.doc(`/mentees/${req.user.handle}`).update(menteeDetails)
    .then(() => {
        return res.status(200).json({ message: 'Details added successfully' });
    }).catch(err => {
        console.error(err);
        return res.status(500).json({ error: err.code });
    })
}

mentors.js

const { db } = require('../util/admin');

const { reduceMentorDetails } = require('../util/validators');

// Add a mentor to the mentors collection
exports.addMentor = (req, res) => {
  let mentorDetails = reduceMentorDetails(req);

  db.doc(`/mentors/${req.user.handle}`)
    .set(mentorDetails)
    .then(() => {
      return res.status(200).json({ message: 'Details added successfully' });
    })
    .catch((err) => {
      console.error(err);
      return res.status(500).json({ error: err.code });
    });
};

// Get all mentors from the mentor collection
exports.getMentors = (req, res) => {
  db.collection('mentors')
    .get()
    .then((data) => {
      let mentors = [];
      data.forEach((doc) => {
        mentors.push(doc.data());
      });
      return res.json(mentors);
    })
    .catch((err) => {
      console.error(err);
      return res.status(500).json({ error: err.code });
    });
};

// Update an existing mentor
exports.updateMentor = (req, res) => {
  let mentorDetails = reduceMentorDetails(req);

  db.doc(`/mentors/${req.user.handle}`)
    .update(mentorDetails)
    .then(() => {
      return res.status(200).json({ message: 'Details added successfully' });
    })
    .catch((err) => {
      console.error(err);
      return res.status(500).json({ error: err.code });
    });
};

validators.js

// Helper functions for validation of signup form
// Check if a field is empty
const isEmpty = (string) => {
  if (string.trim() === '') return true;
  else return false;
};

// Check if an email is valid in format
const isEmail = (email) => {
  const regEx =
    /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
  if (email.match(regEx)) return true;
  else return false;
};

//Validate signup credential entered
exports.validateSignupData = (data) => {
  let errors = {};

  if (isEmpty(data.email)) {
    errors.email = 'Must not be empty';
  } else if (!isEmail(data.email)) {
    errors.email = 'Must be a valid email';
  }
  if (isEmpty(data.password)) errors.password = 'Must not be empty';
  if (data.password !== data.confirmPassword)
    errors.confirmPassword = 'Passwords do not match';
  if (isEmpty(data.handle)) errors.handle = 'Must not be empty';

  return {
    errors,
    valid: Object.keys(errors).length === 0 ? true : false,
  };
};

// Validate Login Credentials entered
exports.validateLoginData = (data) => {
  let errors = {};
  if (isEmpty(data.email)) errors.email = 'Must not be empty';
  if (isEmpty(data.password)) errors.password = 'Must not be empty';

  return {
    errors,
    valid: Object.keys(errors).length === 0 ? true : false,
  };
};

// User Details Updater - Checks for non-answers/blanks and return dict
exports.reduceUserDetails = (data) => {
  let userDetails = {};

  if (!isEmpty(data.fullName.trim())) userDetails.fullName = data.fullName;
  if (!isEmpty(data.jobTitle.trim())) userDetails.jobTitle = data.jobTitle;
  if (!isEmpty(data.affiliation.trim()))
    userDetails.affiliation = data.affiliation;
  if (!isEmpty(data.homeLocation.trim()))
    userDetails.homeLocation = data.homeLocation;
  if (!isEmpty(data.isLatinX.trim())) userDetails.isLatinX = data.isLatinX;
  if (!isEmpty(data.bio.trim())) userDetails.bio = data.bio;
  if (!isEmpty(data.website.trim())) {
    // If user doesn't include the http://
    if (data.website.trim().substring(0, 4) !== 'http') {
      userDetails.website = `http://${data.website.trim()}`;
    } else userDetails.website = data.website;
  }
  if (!isEmpty(data.publicProfile.trim()))
    userDetails.publicProfile = data.publicProfile;

  return userDetails;
};

// Mentee Details Updater - Checks for non-answers/blanks and return dict
exports.reduceMenteeDetails = (data) => {
  const answers = data.body;
  let menteeDetails = {};

  // Things we can pull from the data.user or just geneate
  menteeDetails.createdAt = new Date().toISOString();
  menteeDetails.userId = data.user.uid;
  menteeDetails.email = data.user.email;
  menteeDetails.handle = data.user.handle;

  //Things we can pull from the user's info in the user collection
  menteeDetails.fullName = answers.fullName;
  menteeDetails.isLatinX = answers.isLatinX;
  menteeDetails.currentLocation = answers.currentLocation;

  // Questions we need to ask in the mentee sign up flow
  if (!isEmpty(answers.gender.trim())) menteeDetails.gender = answers.gender;
  if (!isEmpty(answers.countryOrigin.trim()))
    menteeDetails.countryOrigin = answers.countryOrigin;
  if (!isEmpty(answers.affiliation.trim()))
    menteeDetails.affiliation = answers.affiliation;
  if (!isEmpty(answers.position.trim()))
    menteeDetails.position = answers.position;
  if (!isEmpty(answers.scholarOrWebsite.trim())) {
    // If user doesn't include the http://
    if (answers.scholarOrWebsite.trim().substring(0, 4) !== 'http') {
      menteeDetails.scholarOrWebsite = `http://${answers.scholarOrWebsite.trim()}`;
    } else menteeDetails.scholarOrWebsite = answers.scholarOrWebsite;
  }
  if (answers.languages.length > 0) menteeDetails.languages = answers.languages;
  if (!isEmpty(answers.timezone.trim()))
    menteeDetails.timezone = answers.timezone;
  if (answers.mentorshipArea.length > 0)
    menteeDetails.mentorshipArea = answers.mentorshipArea;
  if (!isEmpty(answers.motivationStatement.trim()))
    menteeDetails.motivationStatement = answers.motivationStatement;
  if (answers.prefferedOutcomes.length > 0)
    menteeDetails.prefferedOutcomes = answers.prefferedOutcomes;
  if (!isEmpty(answers.discussAfter.trim()))
    menteeDetails.discussAfter = answers.discussAfter;
  if (!isEmpty(answers.careerGoals.trim()))
    menteeDetails.careerGoals = answers.careerGoals;
  if (answers.skillMentorship.length > 0)
    menteeDetails.skillMentorship = answers.skillMentorship;
  if (answers.researchAreas.length > 0)
    menteeDetails.researchAreas = answers.researchAreas;
  if (answers.careerAdvice.length > 0)
    menteeDetails.careerAdvice = answers.careerAdvice;
  if (!isEmpty(answers.workshopReviewer))
    menteeDetails.workshopReviewer = answers.workshopReviewer;
  if (!isEmpty(answers.peerReviewedPubs.trim()))
    menteeDetails.peerReviewedPubs = answers.peerReviewedPubs;
  if (!isEmpty(answers.topTierReviewer.trim()))
    menteeDetails.topTierReviewer = answers.topTierReviewer;
  if (!isEmpty(answers.topTierPub.trim()))
    menteeDetails.topTierPub = answers.topTierPub;
  if (!isEmpty(answers.highImpactReviewer.trim()))
    menteeDetails.highImpactReviewer = answers.highImpactReviewer;
  if (answers.conferencePreference.length > 0)
    menteeDetails.conferencePreference = answers.conferencePreference;
  if (!isEmpty(answers.otherConferences.trim())) {
    let conferences = answers.otherConferences.split(',');
    menteeDetails.conferencePreference =
      menteeDetails.conferencePreference.concat(conferences);
  }
  if (!isEmpty(answers.peerReviewedHighImpact))
    menteeDetails.peerReviewedHighImpact = answers.peerReviewedHighImpact;

  return menteeDetails;
};

// Mentee Details Updater - Checks for non-answers/blanks and return dict
exports.reduceMentorDetails = (data) => {
  const answers = data.body;
  let mentorDetails = {};

  // Things we can pull from the data.user or just geneate
  mentorDetails.createdAt = new Date().toISOString();
  mentorDetails.userId = data.user.uid;
  mentorDetails.email = data.user.email;
  mentorDetails.handle = data.user.handle;

  //Things we can pull from the user's info in the user collection
  mentorDetails.fullName = answers.fullName;
  mentorDetails.isLatinX = answers.isLatinX;
  mentorDetails.currentLocation = answers.currentLocation;

  // Questions we need to ask in the mentor sign up flow
  if (!isEmpty(answers.gender.trim())) mentorDetails.gender = answers.gender;
  if (!isEmpty(answers.countryOrigin.trim()))
    mentorDetails.countryOrigin = answers.countryOrigin;
  if (!isEmpty(answers.affiliation.trim()))
    mentorDetails.affiliation = answers.affiliation;
  if (!isEmpty(answers.position.trim()))
    mentorDetails.position = answers.position;
  if (!isEmpty(answers.scholarOrWebsite.trim())) {
    // If user doesn't include the http://
    if (answers.scholarOrWebsite.trim().substring(0, 4) !== 'http') {
      mentorDetails.scholarOrWebsite = `http://${answers.scholarOrWebsite.trim()}`;
    } else mentorDetails.scholarOrWebsite = answers.scholarOrWebsite;
  }
  if (answers.languages.length > 0) mentorDetails.languages = answers.languages;
  if (!isEmpty(answers.timezone.trim()))
    mentorDetails.timezone = answers.timezone;
  if (!isEmpty(answers.previousMentor.trim()))
    mentorDetails.previousMentor = answers.previousMentor;
  if (answers.mentorshipArea.length > 0)
    mentorDetails.mentorshipArea = answers.mentorshipArea;
  if (!isEmpty(answers.hoursAvailable.trim()))
    mentorDetails.hoursAvailable = answers.hoursAvailable;
  if (answers.menteePref.length > 0)
    mentorDetails.menteePref = answers.menteePref;
  if (!isEmpty(answers.otherPref.trim())) {
    let menteePrefs;
    let newPref;
    if (mentorDetails.menteePref.length !== 0)
      menteePrefs = mentorDetails.menteePref;
    else menteePrefs = [];
    newPref = answers.otherPref.split(',');
    menteePrefs = menteePrefs.concat(newPref);
    mentorDetails.menteePref = menteePrefs;
  }
  if (answers.prefferedOutcomes.length > 0)
    mentorDetails.prefferedOutcomes = answers.prefferedOutcomes;
  if (!isEmpty(answers.otherOutcomes.trim())) {
    let outcomes;
    let newPref;
    if (mentorDetails.prefferedOutcomes.length !== 0)
      outcomes = mentorDetails.prefferedOutcomes;
    else outcomes = [];
    newPref = answers.otherPref.split(',');
    outcomes = outcomes.concat(newPref);
    mentorDetails.prefferedOutcomes = outcomes;
  }
  if (!isEmpty(answers.discussAfter.trim()))
    mentorDetails.discussAfter = answers.discussAfter;
  if (answers.skillMentorship.length > 0)
    mentorDetails.skillMentorship = answers.skillMentorship;
  if (answers.researchAreas.length > 0)
    mentorDetails.researchAreas = answers.researchAreas;
  if (answers.careerAdvice.length > 0)
    mentorDetails.careerAdvice = answers.careerAdvice;
  if (!isEmpty(answers.workshopReviewer))
    mentorDetails.workshopReviewer = answers.workshopReviewer;
  if (!isEmpty(answers.peerReviewedPubs.trim()))
    mentorDetails.peerReviewedPubs = answers.peerReviewedPubs;
  if (!isEmpty(answers.topTierReviewer.trim()))
    mentorDetails.topTierReviewer = answers.topTierReviewer;
  if (!isEmpty(answers.topTierPub.trim()))
    mentorDetails.topTierPub = answers.topTierPub;
  if (!isEmpty(answers.highImpactReviewer.trim()))
    mentorDetails.highImpactReviewer = answers.highImpactReviewer;
  if (answers.conferencePreference.length > 0)
    mentorDetails.conferencePreference = answers.conferencePreference;
  if (!isEmpty(answers.otherConferences.trim())) {
    let otherconferences = answers.otherConferences.split(',');
    let conferences = mentorDetails.conferencePreference;
    conferences = conferences.concat(otherconferences);
    mentorDetails.conferencePreference = conferences;
  }
  if (!isEmpty(answers.peerReviewedHighImpact))
    mentorDetails.peerReviewedHighImpact = answers.peerReviewedHighImpact;

  return mentorDetails;
};
like image 227
TMac Avatar asked May 18 '26 16:05

TMac


1 Answers

According to the error message, there isn't a whole lot of information about the problem you're presenting. I know you used firebase –-debug deploy to retrieve the error message, and it returned an error on the user code, but what I would advise is that you look into the issue by viewing the log using firebase functions:log, which would be a lot easier.

There will be a visible representation of the exact issue. It could be something as simple as a missing package in some cases.

You can also use the following: firebase functions:log --only <FUNCTION_NAME>

To have a better understanding of this command, you can access the Write and view logs.

like image 165
Jose German Perez Sanchez Avatar answered May 21 '26 07:05

Jose German Perez Sanchez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!