Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync existing user email addresses when connecting Mailchimp Extension to Firebase #29

Open
dackers86 opened this issue Nov 24, 2021 · 6 comments
Labels
enhancement New feature or request needs investigation Investigation needed to find more information, e.g. is this a bug, is the feature viable.

Comments

@dackers86
Copy link
Collaborator

Moving from firebase/extensions#415

@papmodern
Copy link

Any update???

I could understand there is a PR related to this issue, but nothing mentioned in the main doc ad repo

@barticus barticus added enhancement New feature or request needs investigation Investigation needed to find more information, e.g. is this a bug, is the feature viable. labels May 17, 2022
@barticus
Copy link
Collaborator

Hi @dackers86 ,

Thanks for raising this.

This might be best delivered as a function that is deployed but manually triggered by the user to read through all existing users. We'll scope this out.

Regards,

@MasterScrat
Copy link

Any news on this? This issue really limits the ease of use of the extension, as either it needs to be setup from the start of the project's lifetime, or it requires writing a custom script that has large overlap with what the extension does 🤔

@barticus
Copy link
Collaborator

barticus commented Apr 4, 2023

Hi @MasterScrat , are you expecting all data to be synced (e.g. merge fields, tags, activities)? I've been looking at how to get #52 merged but it is currently limited to just auth details (email + status). Also there are some testing difficulties.
However, we could extend on the pattern there.
The solution would need to iterate through the indicated firestore collection paths, probably with a user defined filter or at least looking for documents with the subscriberEmail indicated field set, and then treat it as an "insert" (no before document). We'd need to also test to handle high volumes and verify any mailchimp limits.

As a workaround, so you're not recreating any functionality in the extension:

  1. Create a new collection, or subcollection if you were using a subcollection
  2. Update the extension to point to this new collection
  3. Write a script to copy between the two collections. List all documents in the existing collection and then create a document in the new collection. It might be something like:
import { doc, setDoc, collection, getDocs } from "firebase/firestore"; 
const allDocs = await getDocs(collection(db, "EXISTING_COLLECTION_PATH"));
allDocs.forEach(async (d) => {
  await setDoc(doc(db, "NEW_COLLECTION_PATH", d.id), d.data());
});
  1. Run the script
  2. Update the extension to point back to the existing collection
  3. Write a script to clean up the temporary collection
import { doc, deleteDoc } from "firebase/firestore"; 

const allDocs = await getDocs(collection(db, "NEW_COLLECTION_PATH"));
allDocs.forEach(async (d) => {
  await deleteDoc(doc(db, "NEW_COLLECTION_PATH", d.id));
});

We will look towards supporting natively syncing on install/update but as I cannot commit to a timeline the above might be help someone in the meantime.

@mklsk
Copy link

mklsk commented May 3, 2023

@barticus thanks for posting the workaround! Seems a bit clunky at the moment, to be entirely fair 🫠

Love your idea here:

This might be best delivered as a function that is deployed but manually triggered by the user to read through all existing users.

Would be great to see it come through!

@BilalAtique
Copy link

Hi @MasterScrat , are you expecting all data to be synced (e.g. merge fields, tags, activities)? I've been looking at how to get #52 merged but it is currently limited to just auth details (email + status). Also there are some testing difficulties. However, we could extend on the pattern there. The solution would need to iterate through the indicated firestore collection paths, probably with a user defined filter or at least looking for documents with the subscriberEmail indicated field set, and then treat it as an "insert" (no before document). We'd need to also test to handle high volumes and verify any mailchimp limits.

As a workaround, so you're not recreating any functionality in the extension:

  1. Create a new collection, or subcollection if you were using a subcollection
  2. Update the extension to point to this new collection
  3. Write a script to copy between the two collections. List all documents in the existing collection and then create a document in the new collection. It might be something like:
import { doc, setDoc, collection, getDocs } from "firebase/firestore"; 
const allDocs = await getDocs(collection(db, "EXISTING_COLLECTION_PATH"));
allDocs.forEach(async (d) => {
  await setDoc(doc(db, "NEW_COLLECTION_PATH", d.id), d.data());
});
  1. Run the script
  2. Update the extension to point back to the existing collection
  3. Write a script to clean up the temporary collection
import { doc, deleteDoc } from "firebase/firestore"; 

const allDocs = await getDocs(collection(db, "NEW_COLLECTION_PATH"));
allDocs.forEach(async (d) => {
  await deleteDoc(doc(db, "NEW_COLLECTION_PATH", d.id));
});

We will look towards supporting natively syncing on install/update but as I cannot commit to a timeline the above might be help someone in the meantime.

Considering this approach. I wrote a function and run it locally:

import { onRequest } from "firebase-functions/v2/https";
import * as admin from "firebase-admin";

if (!admin.apps.length) admin.initializeApp();

const migrateData = async () => {
  const db = admin.firestore();
  const existingCollection = db.collection("users");
  const newCollection = db.collection("temp-users");

  const allDocs = (await existingCollection.get()).docs;

  const result = await Promise.all(
    allDocs.map(async (doc) => {
      const docData = doc.data();
      try {
        await newCollection.doc(doc.id).set(docData);
        const successStr = `${docData.username} is migrated successfully`;
        console.log(successStr);
        return successStr;
      } catch (error) {
        return `${docData.username} migration failed`;
      }
    })
  );
  return result;
};

const copyExistingUsersToTempCollection = onRequest(async (req, res) => {
  try {
    const result = await migrateData();
    res.send(result);
  } catch (error) {
    console.log(error);
    res.send(error);
  }
});

export default copyExistingUsersToTempCollection;

Although it saves time, it misses tags and merge fields for many contacts. So, I have updated them manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs investigation Investigation needed to find more information, e.g. is this a bug, is the feature viable.
Projects
None yet
Development

No branches or pull requests

6 participants