I keep get a header error and I'm not sure where it is coming from:
(node:20635) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
> at ServerResponse.setHeader (_http_outgoing.js:526:11)
> at ServerResponse.header (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:771:10)
> at ServerResponse.send (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:170:12)
> at ServerResponse.json (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:267:15)
> at ServerResponse.send (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:158:21)
> at /Users/XXXX/Sites/XXXX/functions/src/controllers/embassies.js:95:48
> at processTicksAndRejections (internal/process/task_queues.js:97:5)
> (node:20635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
> (node:20635) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm using Axios to call the external Mapbox APIs. I've tried .catch() on everything but I can't shake this error. I'm wondering if I can't do two external calls within the same function but I can't confirm that — is this possible?
I'm trying to update the restaurant with the new details and once update I want to get the latitude and longitude of the address and save it to the database as well. Once that is done, I want to get the image of the Map using the latitude and longitude and then upload this image to the Firebase storage.
Here is my functions code:
static update(collectionData, storage, country, restaurant, body, res) {
const countryData = collectionData.where('countryCode', '==', country.toUpperCase()).limit(1);
return countryData.get()
.then(data => {
const restaurantData = data.docs[0].ref.collection('restaurants');
return restaurantData.where('country', '==', restaurant.toUpperCase()).limit(1);
})
.then(restaurantCollection => {
return restaurantCollection.get()
.then(restaurants => {
restaurants.forEach(doc => {
let restaurant = doc.data();
// Set the document with the body data
return doc.ref.set(body, {merge: true})
.then(() => {
let address = restaurant.addressLine1 + ' ' + (restaurant.addressLine2 ? (restaurant.addressLine2 + ' ') : "") + restaurant.suburb + ' ' + (restaurant.state ? (restaurant.state + ' ') : "") + (restaurant.postcode ? (restaurant.postcode + ' ') : "") + restaurant.country;
return axios.get('https://api.mapbox.com/geocoding/v5/mapbox.places/' + address + '.json?limit=1&types=address&access_token=XXXXXX')
.then(function (response) {
doc.ref.set({
"longitude": response.data.features[0].geometry.coordinates[0],
"latitude": response.data.features[0].geometry.coordinates[1]
}, {merge: true});
return response.data.features[0].geometry.coordinates;
})
.catch(function (error) {
return res.send(error);
});
})
.then(geoData => {
let marker = 'https%3A%2F%2Fuploads-ssl.webflow.com%XXXXXX%XXXXXX-marker.png';
console.log(geoData);
return axios.get('https://api.mapbox.com/styles/v1/XXX/XXXX/static/url-' + marker + '(' + geoData[0] + ',' + geoData[1] + ')' + '/' + geoData[0] + ',' + geoData[1] + ',14,0/800x800?access_token=XXXXXX')
.then(function (response) {
storage.ref('restaurant-maps/' + country + '-' + restaurant.toLowerCase() + '.png').put(response)
.then(() => {
console.log('Uploading Map: restaurant-maps/' + country + '-' + restaurant.toLowerCase() + '.png');
})
.catch(function (error) {
return res.send(error);
});
})
.catch(function (error) {
return res.send(error);
});
})
.catch(err => {
return res.send(err);
});
});
return res.status(200).send('restaurant has been updated!');
})
.catch(err => {
return res.status(404).send('Error finding restaurants for this country: ' + err);
});
})
.catch(err => {
return res.status(404).send('Error updating restaurant for this country: ' + err);
});
}