Reputation: 57
I am trying to send a post request to the App Store verifyReceipt endpoint in a Firebase cloud function. However, I get the following error in the cloud function log:
{ Error: read ECONNRESET
at TLSWrap.onread (net.js:622:25)
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read',
However, this error is only occasional. It does not happen every time, so the function obviously works, but something is going wrong sometimes and I'm not sure what.
Most other solutions relating to this were due to a promise error, but I do not believe that is the problem here. Below is the complete function:
exports.handleSubscriptionIAP_IOS_S2S = functions.https.onRequest((req, res) => {
let data = req.body;
console.log('received ios s2s notification with body:', data);
let base64String = data.unified_receipt.latest_receipt;
let boolStatus = true;
// The user has changed the auto renewal status, store the change
if(data.notification_type === 'DID_CHANGE_RENEWAL_STATUS') {
boolStatus = (data.auto_renew_status === 'true');
}
console.log(data.notification_type);
if(base64String) {
var options = {
method: 'post',
url: 'https://buy.itunes.apple.com/verifyReceipt',
data: ({
"receipt-data" : base64String,
"password" : "***",
"exclude-old-transactions" : true
})
};
var optionsSandbox = {
method: 'post',
url: 'https://sandbox.itunes.apple.com/verifyReceipt',
data: ({
"receipt-data" : base64String,
"password" : "***",
"exclude-old-transactions" : true
})
};
return axios(options)
.then((response) => {
if(response.data.status === 21007) {
return 'handle_sandbox';
}
// Got valid response from Apple, pass down chain
else {
return response;
}
})
.then((response) => {
// Send post request to sandbox endpoint
if(response === 'handle_sandbox') {
return axios(optionsSandbox);
}
// Pass response down chain
else {
return response;
}
})
.then((response) => {
// Handle response from Apple verifyReceipt endpoint here
// Both production and sandbox will end up here
// See here for values in response.data: https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info
console.log('received ios s2s notification verify receipt response with body:', response.data);
// Status 0 means request is valid
if(response.data.status === 0) {
// Get receipt info of latest receipt
// Only one object in array is return since we exclude old transactions
let latestReceipt = response.data.latest_receipt_info[0];
// Save receipt into Firestore
return db.collection('appStoreReceipts').doc(latestReceipt.original_transaction_id).set({
latest_receipt_info: latestReceipt,
expiresTimestamp: admin.firestore.Timestamp.fromMillis(parseInt(latestReceipt.expires_date_ms)),
originalTransactionID: latestReceipt.original_transaction_id,
autoRenewStatus: boolStatus,
base64Receipt: response.data.latest_receipt,
}, { merge: true });
}
else {
return null;
}
})
.then((result) => {
if(result) {
return res.status(200).end();
}
else {
return res.status(400).end();
}
})
.catch((error) => {
console.log('an error occured handling the subscription', error);
return res.status(400).end();
})
}
else {
console.log('invalid receipt', data);
return res.status(400).end();
}
});
Thank you for any help that you can give!
Upvotes: 2
Views: 15287
Reputation: 317712
ECONNRESET just means that the other end of the connection closed it. That could mean any number of things. It's probably not your code's fault, unless you've done something so bad in this one request that Apple decided to close the connection. You should contact their support directly if you think they're doing this incorrectly.
Upvotes: 4