mixpanel-react-native icon indicating copy to clipboard operation
mixpanel-react-native copied to clipboard

Expo managed workflow support

Open Ziker22 opened this issue 3 years ago • 25 comments

Hello is there some workaround (except calling REST API directly) for using this with non ejected expo app ?

Ziker22 avatar Aug 04 '21 10:08 Ziker22

Also very interested for my app

jmcoder1 avatar Oct 29 '21 18:10 jmcoder1

seems like there is no update on this. At the moment I segment supports mixpanel and I think you can install it that way but the huge downside is that segment only tracks 1k monthly users vs the 10k that mixpanel does

HosAkh avatar Nov 27 '21 23:11 HosAkh

You can use this library with the Expo managed workflow without ejecting with EAS Build. It will only work on standalone builds though and not on Expo Go. But it's perfectly usable.

gmerino92 avatar Dec 21 '21 17:12 gmerino92

You can use this library with the Expo managed workflow without ejecting with EAS Build. It will only work on standalone builds though and not on Expo Go. But it's perfectly usable.

@gmerino92 could you share how you set it up? I installed 'mixpanel-react-native', imported it in my App.tsx and tried to initialize with:

const mixpanel = new Mixpanel([tokenString])
mixpanel.init()

But I get these errors when attempting to run my app on Expo Go. Did you conditionally import Mixpanel based on if it's a production build?

Error: mixpanel-react-native: MixpanelReactNative is null. 
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.

vanessajbell avatar Mar 29 '22 23:03 vanessajbell

You can use this library with the Expo managed workflow without ejecting with EAS Build. It will only work on standalone builds though and not on Expo Go. But it's perfectly usable.

@gmerino92 could you share how you set it up? I installed 'mixpanel-react-native', imported it in my App.tsx and tried to initialize with:

const mixpanel = new Mixpanel([tokenString])
mixpanel.init()

But I get these errors when attempting to run my app on Expo Go. Did you conditionally import Mixpanel based on if it's a production build?

Error: mixpanel-react-native: MixpanelReactNative is null. 
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.

Someone from Expo answered my question. The problem I was running into was that installing Mixpanel was causing my app to crash when I tried to run it in Expo Go. The reason is that Mixpanel does not work at all in Expo Go, but it does work if you build a development client and it works once you've built the app and distributed it. So there are two options while you’re developing (as of Expo 44):

  1. Install Mixpanel and use a development client. You can build the app with EAS Build locally or on the cloud. Info for local builds here: https://docs.expo.dev/build-reference/local-builds/ https://docs.expo.dev/app-signing/local-credentials/ This means you will no longer be able to use Expo Go, but you’re staying in the Expo managed workflow.

  2. Conditionally import Mixpanel so that it’s skipped in Expo Go: https://docs.expo.dev/bare/using-expo-client/#use-conditional-inline-requires-to-provide-fallbacks

We decided to go with option 2 since we aren’t concerned about testing Mixpanel in development. Hope this helps someone else who was hunting around for answers!

vanessajbell avatar Mar 31 '22 15:03 vanessajbell

Thanks @vanessajbell, option 2 worked great for me.

For those of you who just want a copy/paste solution. This approach:

  • tries to keep typing working by importing just the types from the Mixpanel library directly
  • allows you to do debug logging of the mixpanel calls while in Expo Go mode
  • won't silently fail if something bad actually does happen when initializing the library in production

Any improvements welcome!

import Constants, { ExecutionEnvironment } from 'expo-constants';
import type { Mixpanel } from 'mixpanel-react-native';

const isExpoGo =
  Constants.executionEnvironment === ExecutionEnvironment.StoreClient;

let mixpanel: Mixpanel; /* eslint-disable-line import/no-mutable-exports */

// cache the mixpanel instance so we don't have to re-initialize it
if (!mixpanel) {

  // Check if we're in Expo Go. We could alternatively use a try/catch block,
  // but that could mask other errors. For example, if we're in a production build
  // and something goes wrong during initialization, it will silently fail and
  // we'll just stop getting Mixpanel events. No good.
  if (isExpoGo) {
    mixpanel = createLoggingProxy();
  } else {
    const trackAutomaticEvents = true;
    const { Mixpanel } = require('mixpanel-react-native');
    mixpanel = new Mixpanel('MY_MIXPANEL_TOKEN', trackAutomaticEvents);
    mixpanel.init();
  }
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
function createLoggingProxy() {
  return new Proxy(
    {},
    {
      get(target, prop) {
        if (target[prop] === undefined)
          return function (...args) {
            console.debug(`${String(prop)} called with:`, args);
          };
        return target[prop];
      },
    },
  );
}

export default mixpanel;

steviec avatar Feb 08 '23 00:02 steviec

You can use this library with the Expo managed workflow without ejecting with EAS Build. It will only work on standalone builds though and not on Expo Go. But it's perfectly usable.

@gmerino92 could you share how you set it up? I installed 'mixpanel-react-native', imported it in my App.tsx and tried to initialize with:

const mixpanel = new Mixpanel([tokenString])
mixpanel.init()

But I get these errors when attempting to run my app on Expo Go. Did you conditionally import Mixpanel based on if it's a production build?

Error: mixpanel-react-native: MixpanelReactNative is null. 
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.

Hi, Vanessa. Sorry I missed this. Indeed, like you said in your next response, we have a conditional import for the library so as to avoid errors while in development. We don't use Expo Go anymore though, only develop using dev clients built with EAS Build. This is an excerpt of what we do:

const MixpanelWrapper: any = require('mixpanel-react-native');

    if (MixpanelWrapper) mixpanel = new MixpanelWrapper.Mixpanel(token);
    if (mixpanel) {
        mixpanel.init();
        mixpanel.setLoggingEnabled(true);
    }

gmerino92 avatar Apr 14 '23 14:04 gmerino92

@gmerino92 is there any way to use with dev clients built locally via the npx expo run:ios command?

anirudhsama avatar Apr 15 '23 08:04 anirudhsama

@gmerino92 is there any way to use with dev clients built locally via the npx expo run:ios command?

Yes this is possible. As far as I know they are the same thing. Build from cloud or locally.

hyochan avatar May 05 '23 16:05 hyochan

Hi I managed to get mixpanel working using eas build. But when I try to run on web it throws erro mixpanel-react-native: MixpanelReactNative is null. Is there any workarround?

saurabhg138 avatar May 30 '23 07:05 saurabhg138

You will have to install the mix panel web library to use it on web.

anirudhsama avatar May 31 '23 05:05 anirudhsama

Hi @anirudhsama Do you have any reference on how to do this ? It should work for both native as well as web

saurabhg138 avatar May 31 '23 05:05 saurabhg138

Not specifically for mixpanel but here is an example of using react-native-firebase on native and firebase on web. https://github.com/nandorojo/nextjs-conf-22-example/tree/setup/packages/app/features/auth/firebase

More details: https://solito.dev/recipes/platform-code

anirudhsama avatar May 31 '23 06:05 anirudhsama

Thank you @anirudhsama it worked

saurabhg138 avatar May 31 '23 11:05 saurabhg138

Does this package work anymore? (https://github.com/benawad/expo-mixpanel-analytics) Trying to use it for my first time, and it either doesn't work or my code is wrong (likely).

joshAntoniuk avatar Jul 04 '23 22:07 joshAntoniuk

It works. I'm using it in my app.

anirudhsama avatar Jul 05 '23 11:07 anirudhsama

@anirudhsama would you be willing to help me with setting it up? I can't find any resources online...

joshAntoniuk avatar Jul 05 '23 15:07 joshAntoniuk

If you are using Expo Go, it will have an issue, but it will work in production. To mitigate that issue, I used this snippet:

import Constants, { ExecutionEnvironment } from "expo-constants";
import type { Mixpanel } from "mixpanel-react-native";

import { Env } from "app/env";

const isExpoGo =
	Constants.executionEnvironment === ExecutionEnvironment.StoreClient;

let mixpanel: Mixpanel;

// Check if we're in Expo Go or in an expo-dev-client. We could alternatively use a try/catch block,
// but that could mask other errors. For example, if we're in a production build
// and something goes wrong during initialization, it will silently fail and
// we'll just stop getting Mixpanel events. No good.
if (isExpoGo) {
	mixpanel = createLoggingProxy();
} else {
	const { Mixpanel } = require("mixpanel-react-native");
	const trackAutomaticEvents = true;
	mixpanel = new Mixpanel(Env.MIXPANEL_PROJECT_TOKEN, trackAutomaticEvents);
	mixpanel.init();
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
function createLoggingProxy() {
	return new Proxy(
		{},
		{
			get(target: any, prop) {
				if (target[prop] === undefined)
					return function (...args: any) {
						alert("Mixpanel debug");
						console.debug(`MIXPANEL: ${String(prop)} called with:`, args);
					};
				return target[prop];
			},
		}
	);
}

export default mixpanel;

Import this file in App.tsx so that it is initialised.

anirudhsama avatar Jul 06 '23 05:07 anirudhsama

@anirudhsama What do you use for testing the app? (not unit tests, just checking if the data goes to Mixpanel)

joshAntoniuk avatar Jul 10 '23 21:07 joshAntoniuk

I use a proxy to see if the API calls are being made to Mixpanel. Apart from that I also just look at the mixpanel events dashboard after a while to see if the events have come through.

anirudhsama avatar Jul 11 '23 06:07 anirudhsama

I use a proxy to see if the API calls are being made to Mixpanel. Apart from that I also just look at the mixpanel events dashboard after a while to see if the events have come through.

And you do this through an EAS Build? Or if you test on Expo with the condition would it still trigger an event?

joshAntoniuk avatar Jul 11 '23 16:07 joshAntoniuk

Yes, I create a build on EAS, install on device and do the checks.

anirudhsama avatar Jul 13 '23 06:07 anirudhsama

You can use this library with the Expo managed workflow without ejecting with EAS Build. It will only work on standalone builds though and not on Expo Go. But it's perfectly usable.

@gmerino92 could you share how you set it up? I installed 'mixpanel-react-native', imported it in my App.tsx and tried to initialize with:

const mixpanel = new Mixpanel([tokenString])
mixpanel.init()

But I get these errors when attempting to run my app on Expo Go. Did you conditionally import Mixpanel based on if it's a production build?

Error: mixpanel-react-native: MixpanelReactNative is null. 
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.

You can start your metro in long Folder, you can stop your all metros to your project and open the project it will be worked

VinayMange1311 avatar Sep 07 '23 06:09 VinayMange1311

I'm using a combo of what @steviec and @anirudhsama included, where I'm both caching the mixpanel object and I'm getting the mixpanel token from an env file. This code is mostly duplicate from their answers but in case others want an easy way to copy/paste this with the changes I mentioned:

import Constants, { ExecutionEnvironment } from "expo-constants";
import type { Mixpanel } from "mixpanel-react-native";

import { MIXPANEL_PROJECT_TOKEN } from "@env";

const isExpoGo =
    Constants.executionEnvironment === ExecutionEnvironment.StoreClient;

let mixpanel: Mixpanel;

if (!mixpanel) {
    // Check if we're in Expo Go or in an expo-dev-client. We could alternatively use a try/catch block,
    // but that could mask other errors. For example, if we're in a production build
    // and something goes wrong during initialization, it will silently fail and
    // we'll just stop getting Mixpanel events. No good.
    if (isExpoGo) {
        mixpanel = createLoggingProxy();
    } else {
        const { Mixpanel } = require("mixpanel-react-native");
        const trackAutomaticEvents = true;
        mixpanel = new Mixpanel(MIXPANEL_PROJECT_TOKEN, trackAutomaticEvents);
        mixpanel.init();
    }
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
function createLoggingProxy() {
    return new Proxy(
        {},
        {
            get(target: any, prop) {
                if (target[prop] === undefined)
                    return function (...args: any) {
                        console.debug(
                            `MIXPANEL: ${String(prop)} called with:`,
                            args
                        );
                    };
                return target[prop];
            },
        }
    );
}

export default mixpanel;

bradydowling avatar Feb 07 '24 11:02 bradydowling

Hello, thank you all for your patience. We have just released a beta version, v3.0.0-beta.1. This version allows you to enable JavaScript mode when initializing Mixpanel, which should work with the Expo managed workflow. For more details and installation guidelines, please refer to the release notes at Mixpanel React Native v3.0.0-beta.1. We welcome you to report any issues or provide feedback! 🙏

zihejia avatar Mar 02 '24 01:03 zihejia

Version 3.0.0, which includes support for the Expo managed workflow, has now been released. I'm closing this thread. Please feel free to raise any issues if they arise.

zihejia avatar Apr 09 '24 05:04 zihejia