Kode Bryant
Kode Bryant

Reputation: 511

Get/add Document in Cloud functions using Firestore

I'm struggling a bit with the integration of an automated workflow when a user purchases a product and pays by stripe. I'm using Firestore and Cloud Functions.

Workflow

  1. User purchases Product via Stripe Checkout.js
  2. Payment is stored in 'payments' collection

    { product:<uid of the product> '...', user:<uid of the user> '..', method: 'stripe', token:< Stripe token> {..} }
    
  3. Triggers Cloud function (onWrite for payment collection)

  4. TODO: Get product DocRef from 'products' (retrieve the product's price)
  5. TODO: Add Document to 'purchases' collection inside a document of the collection 'users'

  6. Charge payment

I've implemented this workflow, except for step 4 and 5, because I have no idea how to retrieve and add DocRef from Firestore within Cloud Functions (there are a lot of examples provided by the Firebase Docs on how it works with RT Database)

functions/index.js

exports.stripeCharge = functions.firestore
  .document('/payments/{payment}')
  .onWrite(event => {
    const paymentId = event.params.payment;
    const payment = event.data.data();
    if (!payment || payment.method !== 'stripe' || payment.charge) return;
    // 4. Get Product's Price
    firestore.collection('products').doc(payment.product).then(product => {
      const idempotency_key = paymentId;
      const charge = {
        amount: product.price,
        currency: 'chf',
        source: payment.token.id
      };
      stripe.charges.create(charge, {idempotency_key}).then(charge => {
        // 5. Update User Purchases
        firestore.collection('users').doc(payment.user).collection('purchases').add({
          product: payment.product,
          payment: paymentId,
          date: new Date()
        });
        // Updated Charge
        event.data.ref.update({charge});
      });
    });

Admin SDK I suppose that I have to use Admin SDK to achieve this, but I have no idea on how this is supposed to work with Firestore

Upvotes: 1

Views: 5234

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598847

Accessing Firestore from the Admin SDK is pretty similar to accessing any other Firebase product from the Admin SDK: e.g. admin.firestore()... See https://firebase.google.com/docs/reference/admin/node/firebase-admin.firestore.md#firebase-adminfirestore_module.

You're missing a get() call when you're trying to access the document:

firestore.collection('products').doc(payment.product).get().then(product => {
    if (!product.exists) {
        console.log('No such product!');
    } else {
        console.log('Document data:', product.data());
    }

If you haven't used Firestore from JavaScript before, Cloud Functions is not the easiest way to get started with it. I recommend reading the docs for JavaScript/web users, and taking the Firestore codelab for web developers.

Upvotes: 5

Related Questions