質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

PayPal

PayPalとは、インターネットやメールアドレスを利用した決済サービスのことです。PayPal口座を開設し、送金や入金を行うことができます。クレジットカード番号や口座番号などの情報を取り引き先に知らせる必要がないため、安全なサービスといわれています。アメリカを中心に全世界で多く使用されているオンライン決済サービスです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

2865閲覧

【firestore】トランザクションとイベント処理の組み合わせがうまくできない

KU112

総合スコア1

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

PayPal

PayPalとは、インターネットやメールアドレスを利用した決済サービスのことです。PayPal口座を開設し、送金や入金を行うことができます。クレジットカード番号や口座番号などの情報を取り引き先に知らせる必要がないため、安全なサービスといわれています。アメリカを中心に全世界で多く使用されているオンライン決済サービスです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/07/21 17:12

お世話になります。

現在、FirebaseのFirestoreと、PayPalを使って、支払いが確認できたらデータをDBへ登録するという機能を実装しております。

<困りごと>
支払いまたはDBへの登録のどちらかが失敗したとき、片方の処理がされたまま終わってしまうため、

・DBへの登録が失敗したら、支払いもキャンセルする
・支払いが失敗したら、DBへの登録もキャンセルする

のいずれかの形で整合性を保つのが良いかと考えております。
こういう場面ではFirestoreのトランザクションを使えば実現できるのかと思いましたが、
いまいちどのように組み立てれば良いのかがわかっておりません。

下記にそれぞれのコードを記載しました。
PayPalの方だとpaypal.Buttonsの中で支払いが成功したときはonApproveの中の処理が実行され、
支払いに失敗したときにはonErrorの中の処理が実行されるという仕様になっているはずです。

Firestoreのトランザクションを上手く使って今回実現したいことを行おうとしているのですが、
もしトランザクションの処理の中にこのpaypal.Buttonsを書いたとしても、この.Buttonsメソッドの処理自体のエラーをキャッチしたいわけではないので、うまくいかないと思います。
また例えば支払いが完了した後に(onApproveの中で)トランザクションの処理を書いても、
既に支払いは終わってしまっているので支払いの方をキャンセルすることはできないと思います。

以上のように、どのように実現すれば良いかが分かりません。
もしお分かりになる方がいらっしゃいましたらご教示いただけますと大変助かります。

■Firestoreのトランザクションのドキュメント
https://firebase.google.com/docs/firestore/manage-data/transactions?hl=ja#web-v8

// Create a reference to the SF doc. var sfDocRef = db.collection("cities").doc("SF"); // Uncomment to initialize the doc. // sfDocRef.set({ population: 0 }); return db.runTransaction((transaction) => { // This code may get re-run multiple times if there are conflicts. return transaction.get(sfDocRef).then((sfDoc) => { if (!sfDoc.exists) { throw "Document does not exist!"; } // Add one person to the city population. // Note: this could be done without a transaction // by updating the population using FieldValue.increment() var newPopulation = sfDoc.data().population + 1; transaction.update(sfDocRef, { population: newPopulation }); }); }).then(() => { console.log("Transaction successfully committed!"); }).catch((error) => { console.log("Transaction failed: ", error); });

■PayPalのコード

<script> function initPayPalButton() { paypal.Buttons({ style: { shape: 'rect', color: 'gold', layout: 'vertical', label: 'paypal', }, createOrder: function(data, actions) { return actions.order.create({ purchase_units: [{"amount":{"currency_code":"JPY","value":1}}] }); }, onApprove: function(data, actions) { return actions.order.capture().then(function(details) { alert('Transaction completed by ' + details.payer.name.given_name + '!'); }); }, onError: function(err) { console.log(err); } }).render('#paypal-button-container'); } initPayPalButton(); </script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Firestore (に限らずDB)の transaction 処理はデータベース内の参照と更新の整合性を保つための仕組みです。
(また、transaction 内で外部スコープなどへ変更はするべきではないです)
「外部APIを叩く」「DBの更新をする」の整合性を保つのは例外処理などコードのロジックでやるになります。
並列で実行せず、ログを残しながら同期的に(順番に)行うべきだと思います。

外部APIを叩くの前後でDBなどに記録を取る(push などを用いて)とっておくのが大事かと思います。

あと支払いAPIリクエストの実行中にそのリクエスト実体をキャンセルするという方法は考えないほうが良いと思います。

投稿2021/07/21 23:08

anozon

総合スコア662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KU112

2021/08/05 14:29

ありがとうございました!そのような方向で考えてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問