Я реализовал следующее решение, чтобы подписать пользователя на план, который работает в 99% случаев.Проблема заключается в том, что время от времени приложение отображает сообщение об ошибке, даже если пользователь был успешно подписан.
Процесс выполняется следующим образом:
- Пользователь нажимаетподписаться в приложении, которое затем записывает следующие значения в Firebase
Используя следующие развернутые облачные функции Google, я затем подписываю / отменяю подписку пользователя на план на основе письменного значения для
subscriptionTriggered
выше.Ответ от
Stripe
записывается обратно в
Firebase
, который также содержит ключ
status
.
exports.subscribeCustomer = functions.database.ref('/stripe_customers/{userId}/subscription/subscriptionTriggered')
.onWrite((change, context) => {
const subscriptionTriggered = change.after.val();
if (subscriptionTriggered === true) {
console.log('subscriptionTriggered: ', subscriptionTriggered);
// Look up the Stripe customer id written in createStripeCustomer
return admin.database().ref(`/stripe_customers/${context.params.userId}/customer_id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((customer) => {
return admin.database().ref('/app-config/stripePlan').once('value').then((snapshot) => {
const plan = snapshot.val();
return stripe.subscriptions.create({
customer: customer,
items: [
{
plan: plan,
},
]
});
});
}).then((response) => {
// If the result is successful, write it back to the database
return change.after.ref.parent.child('response').set(response);
//return snap.ref.child('response').set(response);
}).catch((error) => {
// We want to capture errors and render them in a user-friendly way, while
// still logging an exception with StackDriver
return change.after.ref.parent.child('error').set(userFacingMessage(error));
}).then((error) => {
return reportError(error, {user: context.params.userId});
});
} else if (subscriptionTriggered === false) {
console.log('subscriptionTriggered: ', subscriptionTriggered);
return admin.database().ref(`/stripe_customers/${context.params.userId}/subscription/response/id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((sub) => {
return stripe.subscriptions.del(
sub
);
}).then((response) => {
// If the result is successful, write it back to the database
return change.after.ref.parent.child('response').set(response);
//return snap.ref.child('response').set(response);
}).catch((error) => {
// We want to capture errors and render them in a user-friendly way, while
// still logging an exception with StackDriver
return change.after.ref.parent.child('error').set(userFacingMessage(error));
}).then((error) => {
return reportError(error, {user: context.params.userId});
});
}//end else-if
});
Затем приложение ожидает в течение 5 секунд , а затем считывает письменный ответ
status
ключ.И либо загрузит следующий вид, либо отобразит сообщение об ошибке.Проблема заключается в том, что бывают случаи, когда отображается сообщение об ошибке, даже если при проверке ответа на
Firebase
вручную ключ
status
равен
active
, который следуетзатем обработайте соответственно.
У меня такое ощущение, что сети потребовалось больше 5 секунд для записи в Firebase
, поэтому вместо этого возвращается status = canceled
. Есть ли другой способ проверить состояние подписки, вместо того, чтобы просто увеличить время ожидания с 5 секунд до более длительного ожидания, чтобы справиться с задержками в сети?
.
func checkSubscriptionIfSuccessfulAndAction(){
guard let discoverVC = storyboard?.instantiateViewController(withIdentifier: "DiscoverVC") as? DiscoverVC else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(5000)) {
DataService.run.checkUserHasActiveSubscription(handler: { (status) in
print("inside checkSubscriptionIfSuccessfulAndAction status: \(status)")
if status == "active" {
//Subscription was processed successfully and is active
print("Customer Subscribed successfully to view Carousel")
DataService.run.getLatestSubscriptionAndPaymentSourceStatus()
Utilities.run.dismissSVHUD(delay: 0.0)
discoverVC.initData(forVenue: self.venue!)
DispatchQueue.main.async {
self.presentDetail(discoverVC)
}//end DispatchQueue.main.async
} else {
// There was an error Subscribing the customer
print("There was an error processing the charge by Stripe and it returned an error message")
Utilities.run.dismissSVHUD(delay: 1.0)
self.showMessageViaNotificationBannerSwift(message: "oops! We hit a snag, please try again!")
}//end if-else
})//end checkUserHasActiveSubscription
}//end DispatchQueue.main.asyncAfter
}//end func