Home > Net >  How can I create and run a transaction that writes to two Firestore?
How can I create and run a transaction that writes to two Firestore?

Time:03-18

I have two applications, each belonging to a different firebase project.
I want to write to both Firestore with the same transaction.
How can I do this?

import admin from "firebase-admin";

const primaryFirebase = admin.initializeApp();
const secondaryFirebase = admin.initializeApp({ credential }, "secondary");

const primaryFirestore = primaryFirebase.firestore();
const secondaryFirestore = secondaryFirebase.firestore();

const bookId = "<book ID>";
const comment = "some text";

const primaryBookReference = primaryFirestore.collection("book").doc(bookId);
if ((await primaryBookReference.get()).exists) return;

const secondaryBookReference = secondaryFirestore.collection("book").doc(bookId);
if ((await secondaryBookReference.get()).exists) return;

// TODO: same transaction
const primaryCommentReference = primaryBookReference.collection("comment").add(comment);
const secondaryCommentReference = secondaryBookReference.collection("comment").add(comment);

CodePudding user response:

There is no way to run a transaction across Firestore instances. You will have to find another way to write the data, for example you might check if a three-phase commit is possible across two databases.

CodePudding user response:

I assume that you want to write a new document on both of your Firestore at the same time. Make sure that you put both the credential of your Firestore on each initialization:

const primaryFirebase = admin.initializeApp(
  {
    apiKey: "xxxx",
    authDomain: "xxxxxx",
    databaseURL: "xxxxx",
    projectId: "PROJECTID1",
    storageBucket: "xxxxx",
    messagingSenderId: "xxxxx",
    appId: "xxxxx",
    measurementId: "xxxxx"
  }
);
const secondaryFirebase = admin.initializeApp(
  {
    apiKey: "xxxx",
    authDomain: "xxxxxx",
    databaseURL: "xxxxx",
    projectId: "PROJECTID2",
    storageBucket: "xxxxx",
    messagingSenderId: "xxxxx",
    appId: "xxxxx",
    measurementId: "xxxxx"
  },
  "secondary"
);

const primaryFirestore = primaryFirebase.firestore();
const secondaryFirestore = secondaryFirebase.firestore();

Then you can continue with your code. Your comment should be an object not a string.

const bookId = "<book ID>";
const comment = {fieldName: "some text"};

For reference, here's the full code:

const primaryFirebase = admin.initializeApp(
  {
    apiKey: "xxxx",
    authDomain: "xxxxxx",
    databaseURL: "xxxxx",
    projectId: "PROJECTID1",
    storageBucket: "xxxxx",
    messagingSenderId: "xxxxx",
    appId: "xxxxx",
    measurementId: "xxxxx"
  }
);
const secondaryFirebase = admin.initializeApp(
  {
    apiKey: "xxxx",
    authDomain: "xxxxxx",
    databaseURL: "xxxxx",
    projectId: "PROJECTID2",
    storageBucket: "xxxxx",
    messagingSenderId: "xxxxx",
    appId: "xxxxx",
    measurementId: "xxxxx"
  },
  "secondary"
);

const primaryFirestore = primaryFirebase.firestore();
const secondaryFirestore = secondaryFirebase.firestore();

const bookId = "<book ID>";
const comment = {fieldName: "some text"};

  const primaryBookReference = primaryFirestore.collection("users").doc(bookId);
  primaryBookReference.get()
  .then((doc) => {
    console.log(doc.data());
  })
  .catch((error) => {
    console.log(error)
  });  
  
  const secondaryBookReference = secondaryFirestore.collection("users").doc(bookId);
  secondaryBookReference.get()
  .then((doc) => {
    console.log(doc.data());
  })
  .catch((error) => {
    console.log(error)
  });

// TODO: same transaction
primaryBookReference
.collection("comment")
.add(comment)
.then((docRef) => {
  console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
  console.error("Error adding document: ", error);
});

secondaryBookReference
.collection("comment")
.add(comment)
.then((docRef) => {
  console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
  console.error("Error adding document: ", error);
});

You could also incorporate the write when the document exists on your document reference.

  const primaryBookReference = primaryFirestore.collection("users").doc(bookId);
  primaryBookReference.get()
  .then(() => {
    primaryBookReference
    .collection("comment")
    .add(comment)
    .then((docRef) => {
      console.log("Document written with ID: ", docRef.id);
    })
    .catch((error) => {
      console.error("Error adding document: ", error);
    });
  })
  .catch((error) => {
    console.log("Error getting document:", error);
  });  
  
  const secondaryBookReference = secondaryFirestore.collection("users").doc(bookId);
  secondaryBookReference.get()
  .then(() => {
    secondaryBookReference
    .collection("comment")
    .add(comment)
    .then((docRef) => {
      console.log("Document written with ID: ", docRef.id);
    })
    .catch((error) => {
      console.error("Error adding document: ", error);
    });
  })
  .catch((error) => {
    console.log("Error getting document:", error);
  });
  • Related