Firebase Firestore + cloud function server side verify receipt(in-app-purchase), end result: status 21002 which means: The data in the receipt property was malformed or missing.

step1) I store in-app-purchase receipt into Firestore using swift, Firestore database naturally stored it as blob

step2) Cloud function triggered once the receipt went to firestore. Firebase function send receipt to apple iTunes store, but the end result is: status 21002.

I guess somehow the receipt is in the wrong format during convert it from base64EncodedData to Firestore blob, then retrieve it on cloud function. How do I get the right receipt format so i can send it to apple iTunes store for receipt verification?

step 1 swift code:

func sendReceiptToFirestore() {
        guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
            FileManager.default.fileExists(atPath: appStoreReceiptURL.path) else {return}
        do {
            let rawReceiptData = try Data(contentsOf: appStoreReceiptURL)
            let receiptData = rawReceiptData.base64EncodedData()
            //Standard way to store receiptData to firestore, i did that but not posting full code here for cleanliness
        }   catch {}
    }

step 2 cloud function code:

const request = require("request-promise");
exports.verifyReceiptIAP = functions.firestore
    .document('userReceiptIAP/{userUid}')
    .onWrite((change, context) => {
        const receipt = change.after.data().receiptData  
        const userUid = context.params.userUid
        var options = {
            method: 'POST',
            url: 'https://sandbox.itunes.apple.com/verifyReceipt',
            body: ({
                "receipt-data" : receipt,
                "password" : "8bf2f13bedc6456f97c9323c743a3168"
            }),
            json: true
        };
            return request(options).then(function (response) {
            console.log(response);
            return null
        })

    });

Any help is appreciated

1 Answers

1
Sculletbutt善 On Best Solutions

Solved it, I need to change the encode method. Change

let receiptData = rawReceiptData.base64EncodedData()

To

let receiptData = rawReceiptData.base64EncodedString()

If you want to do server side receipt verification using firestore and cloud function, sample code on question should help a lot