Segment trackEvent doesn't work right after CodePush update installs - react-native

Our React Native project has both Segment and CodePush integrated.
Segment works fine, normally.
But there's a scenario where Segment stops working right after a CodePush update has been installed. Nothing gets flushed out and none of the events are shown in the Live Debugger list - except for events that are tracked in the native layer (eg: "Application Opened" and "Application Backgrounded" - only these show up).
So I assumed that any Segment call in the RN - Javascript layer only stops working after the app restarts the bundle (by CodePush).
The user should close and kill the app and reopen the app for it to work normally again.
Happens to both iOS and Android (when installed from the store).
And weirdly enough, I cannot recreate the issue on Android when I run a debug or release build directly to my Android phone from my machine (it just works šŸ¤·ā€ā™‚ļø). Same goes for iOS simulators.
Any ideas or workarounds on this?
This is how the setup looks like:
import React, { Component } from "react";
import CodePush from "react-native-code-push";
import segment from "#segment/analytics-react-native";
...
class App extends Component {
constructor(props) {
super(props);
this.setupSegment();
}
private setupSegment(): void {
segment.setup("<Segment Write Key>", {
debug: true,
trackAppLifecycleEvents: true,
ios: {
trackAdvertising: true
}
});
}
...
}
export default CodePush({
installMode: CodePush.InstallMode.IMMEDIATE,
checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME,
updateDialog: null
})(App);
react-native: 0.61.5
react-native-code-push: 6.1.0
#segment/analytics-react-native: 1.1.1-beta.2 (also tried 1.1.1-beta.5)

Related

Android simulator running Expo (React-Native) not showing the new code (doesnĀ“t update)

I am using the expo-cli tool to develop in react native. I am using an android simulator: Once i run "yarn start" the console asks me:
To run the app with live reloading, choose one of:
ā€¢ Scan the QR code above with the Expo app (Android) or the Camera app (iOS).
ā€¢ Press a for Android emulator.
ā€¢ Press e to send a link to your phone with email.
ā€¢ Press s to sign in and enable more options.
I press a. The simulator loads the expo app succesfully but the text displayed is not updated. What i mean with this is that before I just had this on app.js:
export default function App() {
return (
<UtilityThemeProvider>
<Box><Text>Hello App</Text></Box>
</UtilityThemeProvider>
);
}
And indeed it was showing Hello App. But then I installed react navigation and similar dependiencies and i have this on app.js:
export default function App() {
return (
<UtilityThemeProvider>
<Navigation />
</UtilityThemeProvider>
);
}
There is no error showing. Not in the console of the simulator, nor in the console, nor in the metro bundler! But the android simulator still itĀ“s showing Hello App
HereĀ“s how i export and import the Navigator component:
index.js:
export default class Navigation extends Component{
state = {}
render(){
return <AppNavigator />
}
}
App.js:
import Navigation from './src/views/index'
Things iĀ“ve tried:
Restart the simulator device
2- Stop the server and run yarn start again
3- Make sure my IDE is still in autosave mode
Any idea what i could do? Could it be possible that iĀ“ve touched something to disable re-load?
Click on Android simulator Ctrl + M and check if you have Enable Live Reload option

Expo - Lock orientation to landscape

I'm trying to have my expo react-native app displayed in landscape
I edited app.json to have:
"orientation": "landscape",
And this in App.js
import { ScreenOrientation } from 'expo';
export default class App extends React.PureComponent {
// ...
componentDidMount() {
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
}
// ...
}
I try to run in android emulator, but it looks like the emulator is locked on portrait mode.
The physical orientation of the device is landscape, The app is "streched" to fit a landscape screen, but android seems lock in portrait mode:
https://i.ibb.co/dK54ngp/Capture.png
I check the device setting and "Auto-rotate" is ON.
I think I am missing something but I can't find what.
Can someone tell me what needs to be done to lock the app to landscape mode ?
Edit:
It seems to work with the Nexus 5 emulator, not on Nexus 9
for me just changing orientation in app.json is enough, the code is not needed.
change with this.
import * as ScreenOrientation from 'expo-screen-orientation';
ScreenOrientation.unlockAsync()
There are some bugs related to orientation, in the last Expo version.
Check this out: https://github.com/expo/expo/issues/8210

Why Android App showing blank screen when coming out of an App with back button React Native Navigation?

I am working on React Native Application and integrated react-native-navigation package for navigation inside app, link of package
Android App got stuck and show blank screen. This happens if I am closing app using back button in case of Android app. At the end I have a listing screen, after reopen the application it shows blank screen because it's not calling Navigation.registerComponent again, it might be destroying app when closed using back button.
This is a code inside my index.js::
import { Navigation } from "react-native-navigation";
import App from './src/app';
Navigation.registerComponent("appName", () => App);
Killing the app and restarting would fix the stuck on splash screen issue. But shouldn't be stuck in the first place. Just an issue when closing through back button.
Does anyone have a fix for this? Please suggest how can I handle and call my Navigation.registerComponent once again after closing app using back button.
Environment
React Native Navigation version: 2.12.0
React Native version: 0.58
Platform(s) : Android only
To resolve this you need to make modification inside react-native-navigation package. Open NavigationActivity.java file and replace below code with new one:
Replace this code:
#Override
public void invokeDefaultOnBackPressed() {
if (!navigator.handleBack(new CommandListenerAdapter())) {
super.onBackPressed();
}
}
With this one:
#Override
public void invokeDefaultOnBackPressed() {
if (!navigator.handleBack(new CommandListenerAdapter())) {
this.moveTaskToBack(true);
//super.onBackPressed();
}
}
After saving your changes check on android device.

When does the main componentWillUnmount get called for a react-native app

I'm trying to understand how the device OS treats my react-native app when left in the background for a longer time, I'm guessing a whole lot of smart battery-conserving-logic of the OS comes into play.
In my main index.js I'm just doing this:
import { AppRegistry } from 'react-native';
import App from './app/App';
AppRegistry.registerComponent('CopilotApp', () => App);
..so App.js contains my main component of the entire app, which then has a StackNavigator and a bunch of stuff.
My question is - how does the lifecycle work for this main App-component? When will componentWillUnmount get called / will it ever?
I'm trying to keep things clean by removing event listeners and so on in there, but haven't really figured out when / if that will happen.
On Android:
#Override
protected void onDestroy() {
super.onDestroy();
}

Cross-platform React Native file structure

I'm coming from Ionic 2 where I write my code once, and it runs everywhere.
According to this page https://facebook.github.io/react-native/docs/platform-specific-code.html "When building a cross-platform app, you'll want to re-use as much code as possible."
How can I "reuse" code across iOS and Android in ReactNative? In the starter app I see two files: index.ios.js and index.android.js. Is there something like index.js that I can use for sharing across platforms?
It seems like there should be one file for shareable code, since that web page mentioned above also shows how you can use the Platform module to check what OS you are on.
I realize that sometimes you need different behavior on different platforms, but, assuming that my app is simple enough, and my code ends up exactly the same on both platforms, do I have to copy/paste from one to the other? How can I pull same-functionality into itā€™s own file to be shared on both platforms?
What am I missing?
Thanks!
Here's what you can do. Create a file say main.js that will act as your root page.
main.js
import React, { Component } from 'react';
import { Text } from 'react-native';
export default class Main extends Component {
render() {
return (
<Text>Hello world! from both IOS and Android</Text>
);
}
}
Now on your index.android.js and index.ios.js import that main file and register your Main component as root using AppRegistry.
index.android.js and index.ios.js
import React from 'react';
import {
AppRegistry
} from 'react-native';
import Main from './main';
AppRegistry.registerComponent('DemoApp', () => Main);
if you run react-native run-android and react-native run-ios the Main component will be rendered for both the platforms.
All of the Components with No IOS and Android suffix works for both platforms. Like Navigator works for both ios and android but NavigatorIOS works only for ios. So you'll have to make sure that you're using the cross platform components.
If you need to use platform specific components, then you can use platform detection login to do so:
import { Platform } from 'react-native';
if(Platform.OS === 'ios').....
or
if(Platform.OS === 'android')...