Облачная функция Firebase не работает должным образом - PullRequest
0 голосов
/ 18 октября 2019

Я создал функцию для проверки платежей в приложении в Google Play и выполнения некоторых действий, если все в порядке.

это функции:

exports.validatePurchases = functions.firestore
    .document('users/{userID}/purchasesRemoveAds/{documentID}')
    .onCreate(async (snap, context) => {

        const userID = context.params.userID;

        const purchase = snap.data();
        if (!purchase) {
            return null
        } else {
            if (purchase.is_processed === true) {
                console.log('Purchase already processed!, exiting');
                return null;
            }
            // const orderId = context.params.orderId;
            // const dbRoot = event.ref.root;
            const packageName = purchase.packageName;
            const productId = purchase.productId;
            const purchaseToken = purchase.purchaseToken;

            authClient.authorize()
            // authClient.authorize() returns a credentials Object
                .then(credentials => {
                    console.log(credentials, productId, purchaseToken);
                    return playDeveloperApiClient.purchases.products.get({
                        auth: authClient,
                        packageName: packageName,
                        productId: productId,
                        token: purchaseToken
                    });
                })
                // publisher.purchases.products.get() Returns a axiosResponse object with Purchase data within and the status that should be enough for the validation
                .then((axiosResponse) => {
                    console.log(`Status Code: ${axiosResponse.status} Purchase state: ${ axiosResponse.data.purchaseState} ${typeof axiosResponse.status} ${typeof axiosResponse.data.purchaseState}`);
                    if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
                        console.log('ok here');
                        // Your purchase is valid, do your thing
                        return changeShowAdsFalse(userID);
                    } else {
                        console.log(typeof axiosResponse.status);
                    }
                    return null;
                })
                .catch(reason => {
                    console.log(`Rejection Code: ${reason.code}`);
                    console.log(`Rejection Message: ${reason.message}`);
                    return null;
                });


            return null;
        }
    });

Это довольнопросто, он прослушивает базу данных firestore, когда в каталоге появляется новый документ, запускающий функцию. затем он получает данные из документа и получает покупки с помощью playDeveloperApiClient.purchases.products.get, затем проверяет новые данные с помощью axiosResponse и получает статус покупки. После этого он должен проверить статус == 200 и purchaseState == 0, что происходит (и я вижу это, потому что регистрирую эти значения), но оттуда больше ничего не происходит. Если не выполняется ни то, ни другое. Еще одна странная вещь заключается в том, что до того, как первый и второй журналы пройдут почти минуту, а иногда и больше.

У меня есть план на firebase, и у меня нет привязанной кредитной карты.

Я не знаю, что происходит


журнал функции облака:

10:14:22.856 PM
validatePurchases
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions

10:14:23.561 PM
validatePurchases
Function execution took 706 ms, finished with status: 'ok'

10:14:24.457 PM
validatePurchases
{ access_token: 'token.AO-token-token',
  token_type: 'Bearer',
  expiry_date: 1571433263000,
  id_token: undefined,
  refresh_token: 'jwt-placeholder' } 'remove_ads' 'token.AO-token-token'

10:14:27.457 PM
validatePurchases
Status Code: 200 Purchase state: 0 number number

1 Ответ

2 голосов
/ 19 октября 2019

Есть несколько моментов, которые необходимо адаптировать в вашей облачной функции.

Прежде всего вам необходимо настроить свою платежную учетную запись, как указано в журнале ошибок. Очевидно, вы звоните в службу, которая не считается службой, принадлежащей Google, поэтому вам необходимо иметь «активный» план Flame или Blaze. См. https://firebase.google.com/pricing/ (наведите курсор мыши на знак вопроса, который находится сразу после заголовка «Облачные функции»)


Во-вторых, вы выполняете цепочку различных обещаний, выполняя

        authClient.authorize()
            .then(credentials => {
                //....
                return playDeveloperApiClient.purchases.products.get();
            })
            .then((axiosResponse) => {..})
            .catch(reason => {
                //....
                return null;
            });

но вы не возвращаете первое обещание в цепочке: вы должны выполнить return authClient.authorize().


В-третьих, параллельно цепочке обещаний (или в середине) вы выполняете return null;.

        authClient.authorize()
            .then(credentials => {...})
            .then((axiosResponse) => {..})
            .catch(reason => {...});

        return null;   //  <--- !!

или

            .then((axiosResponse) => {
                if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
                    return changeShowAdsFalse(userID);
                } else {
                    console.log(typeof axiosResponse.status);
                    //Here you should do something, i.e. throw an error
                }
                return null;   //  <--- !!
            });

В-четвертых, поскольку вы используете метод then() для цепочки своих обещаний, вы можете удалить ключевое слово async в onCreate() method.


Итак, после настройки вашего платежного аккаунта нужно выполнить следующее. Однако обратите внимание, что я не видел код функции changeShowAdsFalse(), но, исходя из вашего комментария выше, я предполагаю, что она возвращает Обещание.

exports.validatePurchases = functions.firestore
    .document('users/{userID}/purchasesRemoveAds/{documentID}')
    .onCreate((snap, context) => {

        const userID = context.params.userID;
        const purchase = snap.data();

        if (!purchase) {
            return null;
        } else {
            if (purchase.is_processed === true) {
                console.log('Purchase already processed!, exiting');
                return null;
            }

            const packageName = purchase.packageName;
            const productId = purchase.productId;
            const purchaseToken = purchase.purchaseToken;

            return authClient.authorize()
                .then(credentials => {
                    return playDeveloperApiClient.purchases.products.get({
                        auth: authClient,
                        packageName: packageName,
                        productId: productId,
                        token: purchaseToken
                    });
                })
                .then((axiosResponse) => {
                    if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
                        return changeShowAdsFalse(userID);
                    } else {
                        console.log(typeof axiosResponse.status);
                        throw new Error("Wrong type: " + typeof axiosResponse.status);
                    }
                })
                .catch(reason => {
                    console.log(`Rejection Code: ${reason.code}`);
                    console.log(`Rejection Message: ${reason.message}`);
                    return null;
                });

        }

    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...