Skip to content

Commit a3e62e5

Browse files
Use a react-native-get-random-values polyfill instead of expo-crypto (#294)
* use react-native-get-random-values polyfill instead of expo-crypto, add new sample app * Fix Android Gradle plugin version and async initialization in MixpanelExample - Add version 8.7.2 to Android Gradle plugin coordinate in build.gradle - Move mixpanel.init() to useEffect with proper async/await handling - Add initialization state management to prevent tracking before init completes - Add UI status indicators and disable buttons during initialization - Add error handling for initialization failures
1 parent 5b75c48 commit a3e62e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+14736
-5085
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
BUNDLE_PATH: "vendor/bundle"
2+
BUNDLE_FORCE_RUBY_PLATFORM: 1
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
root: true,
3+
extends: '@react-native',
4+
};

Samples/MixpanelExample/.gitignore

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
**/.xcode.env.local
24+
25+
# Android/IntelliJ
26+
#
27+
build/
28+
.idea
29+
.gradle
30+
local.properties
31+
*.iml
32+
*.hprof
33+
.cxx/
34+
*.keystore
35+
!debug.keystore
36+
.kotlin/
37+
38+
# node.js
39+
#
40+
node_modules/
41+
npm-debug.log
42+
yarn-error.log
43+
44+
# fastlane
45+
#
46+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47+
# screenshots whenever they are needed.
48+
# For more information about the recommended setup visit:
49+
# https://docs.fastlane.tools/best-practices/source-control/
50+
51+
**/fastlane/report.xml
52+
**/fastlane/Preview.html
53+
**/fastlane/screenshots
54+
**/fastlane/test_output
55+
56+
# Bundle artifact
57+
*.jsbundle
58+
59+
# Ruby / CocoaPods
60+
**/Pods/
61+
/vendor/bundle/
62+
63+
# Temporary files created by Metro to check the health of the file watcher
64+
.metro-health-check*
65+
66+
# testing
67+
/coverage
68+
69+
# Yarn
70+
.yarn/*
71+
!.yarn/patches
72+
!.yarn/plugins
73+
!.yarn/releases
74+
!.yarn/sdks
75+
!.yarn/versions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
arrowParens: 'avoid',
3+
bracketSameLine: true,
4+
bracketSpacing: false,
5+
singleQuote: true,
6+
trailingComma: 'all',
7+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

Samples/MixpanelExample/App.tsx

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import React, {useEffect, useState} from 'react';
2+
import {
3+
Button,
4+
SafeAreaView,
5+
ScrollView,
6+
StatusBar,
7+
StyleSheet,
8+
Text,
9+
View,
10+
} from 'react-native';
11+
import {Mixpanel} from 'mixpanel-react-native';
12+
13+
const trackAutomaticEvents = true;
14+
const mixpanel = new Mixpanel('Your Project Token', trackAutomaticEvents);
15+
16+
function App(): React.JSX.Element {
17+
const [isInitialized, setIsInitialized] = useState(false);
18+
19+
useEffect(() => {
20+
const initializeMixpanel = async () => {
21+
try {
22+
await mixpanel.init();
23+
setIsInitialized(true);
24+
} catch (error) {
25+
console.error('Failed to initialize Mixpanel:', error);
26+
}
27+
};
28+
29+
initializeMixpanel();
30+
}, []);
31+
const trackEvent = () => {
32+
if (!isInitialized) {
33+
console.warn('Mixpanel not initialized yet');
34+
return;
35+
}
36+
mixpanel.track('Button Pressed', {
37+
source: 'MixpanelExample',
38+
timestamp: new Date().toISOString(),
39+
});
40+
};
41+
42+
const identifyUser = () => {
43+
if (!isInitialized) {
44+
console.warn('Mixpanel not initialized yet');
45+
return;
46+
}
47+
mixpanel.identify('test_user_123');
48+
mixpanel.getPeople().set({
49+
$name: 'Test User',
50+
$email: 'test@example.com',
51+
});
52+
};
53+
54+
const resetUser = () => {
55+
if (!isInitialized) {
56+
console.warn('Mixpanel not initialized yet');
57+
return;
58+
}
59+
mixpanel.reset();
60+
};
61+
62+
return (
63+
<SafeAreaView style={styles.container}>
64+
<StatusBar barStyle="dark-content" />
65+
<ScrollView contentInsetAdjustmentBehavior="automatic">
66+
<View style={styles.header}>
67+
<Text style={styles.title}>Mixpanel React Native Example</Text>
68+
{!isInitialized && (
69+
<Text style={styles.statusText}>Initializing Mixpanel...</Text>
70+
)}
71+
{isInitialized && (
72+
<Text style={styles.statusText}>✓ Mixpanel Ready</Text>
73+
)}
74+
</View>
75+
76+
<View style={styles.buttonContainer}>
77+
<Button
78+
title="Track Event"
79+
onPress={trackEvent}
80+
disabled={!isInitialized}
81+
/>
82+
<View style={styles.spacer} />
83+
<Button
84+
title="Identify User"
85+
onPress={identifyUser}
86+
disabled={!isInitialized}
87+
/>
88+
<View style={styles.spacer} />
89+
<Button
90+
title="Reset User"
91+
onPress={resetUser}
92+
disabled={!isInitialized}
93+
/>
94+
</View>
95+
96+
<View style={styles.info}>
97+
<Text style={styles.infoText}>
98+
Replace 'Your Project Token' with your actual Mixpanel project token.
99+
</Text>
100+
</View>
101+
</ScrollView>
102+
</SafeAreaView>
103+
);
104+
}
105+
106+
const styles = StyleSheet.create({
107+
container: {
108+
flex: 1,
109+
backgroundColor: '#f5f5f5',
110+
},
111+
header: {
112+
padding: 20,
113+
alignItems: 'center',
114+
},
115+
title: {
116+
fontSize: 24,
117+
fontWeight: 'bold',
118+
color: '#333',
119+
},
120+
statusText: {
121+
fontSize: 16,
122+
color: '#666',
123+
marginTop: 8,
124+
textAlign: 'center',
125+
},
126+
buttonContainer: {
127+
padding: 20,
128+
},
129+
spacer: {
130+
height: 10,
131+
},
132+
info: {
133+
padding: 20,
134+
alignItems: 'center',
135+
},
136+
infoText: {
137+
fontSize: 14,
138+
color: '#666',
139+
textAlign: 'center',
140+
},
141+
});
142+
143+
export default App;

Samples/MixpanelExample/Gemfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
source 'https://rubygems.org'
2+
3+
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4+
ruby ">= 2.6.10"
5+
6+
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
7+
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8+
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9+
gem 'xcodeproj', '< 1.26.0'
10+
gem 'concurrent-ruby', '< 1.3.4'
11+
12+
# Ruby 3.4.0 has removed some libraries from the standard library.
13+
gem 'bigdecimal'
14+
gem 'logger'
15+
gem 'benchmark'
16+
gem 'mutex_m'

Samples/MixpanelExample/README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
2+
3+
# Getting Started
4+
5+
> **Note**: Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding.
6+
7+
## Step 1: Start Metro
8+
9+
First, you will need to run **Metro**, the JavaScript build tool for React Native.
10+
11+
To start the Metro dev server, run the following command from the root of your React Native project:
12+
13+
```sh
14+
# Using npm
15+
npm start
16+
17+
# OR using Yarn
18+
yarn start
19+
```
20+
21+
## Step 2: Build and run your app
22+
23+
With Metro running, open a new terminal window/pane from the root of your React Native project, and use one of the following commands to build and run your Android or iOS app:
24+
25+
### Android
26+
27+
```sh
28+
# Using npm
29+
npm run android
30+
31+
# OR using Yarn
32+
yarn android
33+
```
34+
35+
### iOS
36+
37+
For iOS, remember to install CocoaPods dependencies (this only needs to be run on first clone or after updating native deps).
38+
39+
The first time you create a new project, run the Ruby bundler to install CocoaPods itself:
40+
41+
```sh
42+
bundle install
43+
```
44+
45+
Then, and every time you update your native dependencies, run:
46+
47+
```sh
48+
bundle exec pod install
49+
```
50+
51+
For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html).
52+
53+
```sh
54+
# Using npm
55+
npm run ios
56+
57+
# OR using Yarn
58+
yarn ios
59+
```
60+
61+
If everything is set up correctly, you should see your new app running in the Android Emulator, iOS Simulator, or your connected device.
62+
63+
This is one way to run your app — you can also build it directly from Android Studio or Xcode.
64+
65+
## Step 3: Modify your app
66+
67+
Now that you have successfully run the app, let's make changes!
68+
69+
Open `App.tsx` in your text editor of choice and make some changes. When you save, your app will automatically update and reflect these changes — this is powered by [Fast Refresh](https://reactnative.dev/docs/fast-refresh).
70+
71+
When you want to forcefully reload, for example to reset the state of your app, you can perform a full reload:
72+
73+
- **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Dev Menu**, accessed via <kbd>Ctrl</kbd> + <kbd>M</kbd> (Windows/Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (macOS).
74+
- **iOS**: Press <kbd>R</kbd> in iOS Simulator.
75+
76+
## Congratulations! :tada:
77+
78+
You've successfully run and modified your React Native App. :partying_face:
79+
80+
### Now what?
81+
82+
- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
83+
- If you're curious to learn more about React Native, check out the [docs](https://reactnative.dev/docs/getting-started).
84+
85+
# Troubleshooting
86+
87+
If you're having issues getting the above steps to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
88+
89+
# Learn More
90+
91+
To learn more about React Native, take a look at the following resources:
92+
93+
- [React Native Website](https://reactnative.dev) - learn more about React Native.
94+
- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
95+
- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
96+
- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
97+
- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* @format
3+
*/
4+
5+
import React from 'react';
6+
import ReactTestRenderer from 'react-test-renderer';
7+
import App from '../App';
8+
9+
test('renders correctly', async () => {
10+
await ReactTestRenderer.act(() => {
11+
ReactTestRenderer.create(<App />);
12+
});
13+
});

0 commit comments

Comments
 (0)