Background-Fetch: Cannot read property 'configure' of Undefined - react-native

I have been trying to integrate the transistorsoft background-fetch library without success:
https://github.com/transistorsoft/react-native-background-fetch
When I chain any method to the BackgroundFetch component I get the error (attached in this post)
import BackgroundFetch from "react-native-background-fetch";
class TimerScreen extends React.Component {
...
componentDidMount() {
this.configureBackgroundFetch();
}
...
configureBackgroundFetch() {
// Configure BackgroundFetch.
BackgroundFetch.configure({
minimumFetchInterval: 15, // <-- minutes (15 is minimum allowed)
stopOnTerminate: false, // <-- Android-only,
startOnBoot: true, // <-- Android-only
enableHeadless: true
}, async () => {
console.log('BackgroundFetch has started');
BackgroundFetch.finish(BackgroundFetch.FETCH_RESULT_NEW_DATA);
}, (error) => {
console.log('RNBackgroundFetch failed to start')
});
}
...
I haven't been able to find out why the library isn't working. I have used react native link and installed it in package.json
...
{
...
"react-native-background-fetch": "^2.5.3",
...
}
...

The problem was caused by Expokit not being configured correctly to use native modules. I made a bare React Native app and the library worked without returning an error.

Related

Why does my Expo App crash even with an ErrorBoundary?

I added an ErrorBoundary to my app, but even with an ErrorBoundary my app crashes on errors. Here is a snack with some sample code: https://snack.expo.dev/jq6vGCOoP, also included below:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null, hasError: false, errorInfo: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Catch errors in any components below and re-render with error message
this.setState({
error,
hasError: true,
errorInfo,
});
// You can also log error messages to an error reporting service here
}
render() {
if (this.state.hasError) {
// Error path
return (
<View>
<Text>Something went wrong.</Text>
</View>
);
}
// Normally, just render children
return this.props.children;
}
}
export default function App() {
return (
<ErrorBoundary>
<AppInner/>
</ErrorBoundary>
)
}
function AppInner() {
throw new Error('Error here');
return <></>;
}
I've defined my ErrorBoundary and wrapped it around AppInner, a child component in which I manually throw an error. It kind of works, in developer mode when I run my app using expo start, I get a red error which I can dismiss and I can see the Something went wrong error text. However, when I run the app in production mode using expo start --no-dev --minify, the app just crashes. This is also expected if it crashes locally, but I've also tried pushing the app up onto Expo using eas update, and the app also crashes when trying to load it through Expo hosted services.
Anyone have any ideas?

React Native: AWS Amplify Auth.signOut() not working

React Native noob here, trying to implement AWS Amplify authentication flow into my project. But the Auth.signOut() function is not working at all. Nothing happens when I press the logout button.
const onLogOutPressed = async () => {
//Auth.signOut();
try {
await Auth.signOut({ global: true });
} catch (error) {
console.log('Error Logging Out', error);
}
}
My first version was purely Auth.signOut() as that was what the tutorial I was following did. Another guide suggested using the try method so I commented the first Auth function and added the rest.
Some help would be greatly appreciated. Do let me know if more info is required, thanks in advance.
If you're using React Native UI from Amplify and wrapped your component with withAuthenticator, below code should work.
class App extends React.Component {
constructor(props) {
super(props);
};
...
Auth.signOut().then(() => {
this.props.onStateChange(("signedOut");
});
}
// Functional component
const App = (props) => {
...
Auth.signOut().then(() => {
this.props.onStateChange("signedOut", null);
})
}
If you're not using React Native UI, then you need to handle redirection yourself. Auth.signOut() will only clear session.

Partially mock `react-native` module

I'm running unit tests in React Native that need the NativeEventEmitter and NativeModules mocked but leave everything else as passthrough to the real code.
This part seems to be working except when running I get this error.
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'DevSettings' could not be found. Verify that a module by this name is registered in the native binary.
at invariant (../node_modules/invariant/invariant.js:40:15)
at Object.getEnforcing (../node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.js:39:3)
at Object.<anonymous> (../node_modules/react-native/Libraries/NativeModules/specs/NativeDevSettings.js:30:37)
at Object.<anonymous> (../node_modules/react-native/Libraries/Utilities/DevSettings.js:10:1)
Mocking:
jest.mock(
'react-native',
() => ({
...jest.requireActual('react-native'),
NativeEventEmitter: class MockNativeEventEmitter {
// ...
},
NativeModules: {
// ...
},
Platform: {
OS: 'android',
},
})
);
Online searches for this error all point to problems compiling in dev vs release mode, nothing remotely close to what I'm trying to do.
Have you tried importing DevSettings from react-native and adding the same imported module in your mock? This would be the process for every Component/Module being used in your tested component. Something like:
import { DevSettings } from 'react-native`
jest.mock(
'react-native',
() => ({
...jest.requireActual('react-native'),
NativeEventEmitter: class MockNativeEventEmitter {
// ...
},
NativeModules: {
// ...
},
Platform: {
OS: 'android',
},
DevSettings
})
);

Angular 7 cannot receive firebase notification in the foreground

I am setting my website to receive firebase notifications. I can receive it when in the background. But could not when in the foreground. I have followed this tutorial link to set up. https://medium.com/#a.adendrata/push-notifications-with-angular-6-firebase-cloud-massaging-dbfb5fbc0eeb.
I have initialize it in app.module.ts.
I have tried others similar stackoverflow solutions. But none of them is working so far.
I have tried to use AngularFireMessaging, and FirebaseApp. But both of them could not receive notification after sent.
import { FirebaseApp } from '#angular/fire';
import '#firebase/messaging';
import { AngularFireMessaging } from '#angular/fire/messaging';
setUpMessage() {
this.messaging = this.firebaseApp.messaging();
}
setUpFCM() {
this.afMessaging.messaging.subscribe(_messaging => {
_messaging.onMessage = _messaging.onMessage.bind(_messaging);
_messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
});
}
requestPermission() {
this.afMessaging.requestToken.subscribe(token => {
console.log(token);
}, error => {
console.error(error);
});
}
listenToNotifications() {
return this.afMessaging.messages;
}
listenNotifications() {
return this.messaging;
}
In my component.ts file, I initialized them and got the token from firebase. but cannot receive notification in the foreground.
ngOnInit() {
this.fcmTokenService.setUpMessage();
this.fcmTokenService.setUpFCM();
this.fcmTokenService.requestPermission();
this.validation_messages = this.printFormService.printValidationMessage();
this.listenNotification();
this.listenNotification2();
}
private listenNotification() {
this.fcmTokenService.listenToNotifications().subscribe(msg => {
// msg.content = JSON.parse(msg.data.content);
console.log(msg);
});
}
private listenNotification2() {
this.fcmTokenService.listenNotifications().onMessage(msg => {
console.log(msg);
});
}
I expect to receive the notification and console log it, but no result after many hours or retrying with different approaches.
On your firebase-messaging-sw.js or your service worker file?
importScripts('https://www.gstatic.com/firebasejs/7.6.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.6.0/firebase-messaging.js');
should have the same version with your firebase on package.json
"dependencies": {
...
"firebase": "^7.6.0",
...
}
More details here: https://github.com/angular/angularfire/issues/1904#issuecomment-543506629
I found that importScripts version in service Worker & version of library in package.json has to be same.
The import scripts version and the library version in node_modules must be same for foreground messaging subscription to get the data!
This is a Version compatibility issue as far as I figured. just try to use
"firebase": "^5.0.0",
"#angular/fire": "^5.0.0",
override your package.json with these two, run npm install, you will be fine

Simple example for accessing the camera via WebRTC in react-native (Android)

I'm trying to adapt an augmented reality app I wrote in JS that only works in Firefox on Android to a react native app that can work in either Android or iOS. Since I need the camera input, I'm using react-native-webrtc (rather than importing the html and js I have been using, since I'm also trying to reduce framerate lag). I've been trying to parse out the demo here:
https://github.com/oney/RCTWebRTCDemo/blob/master/main.js
But the demo app is quite complex since it is a video chatroom (from what I can surmise). I just need to access the camera and keep it as the background of the app. This is what I have so far:
import React, { Component } from 'react';
import {
AppRegistry,
View,
} from 'react-native';
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
let localStream;
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(sourceInfos => {
let videoSourceId;
for (const i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if(sourceInfo.kind == "video" && sourceInfo.facing == (isFront ? "front" : "back")) {
videoSourceId = sourceInfo.id;
}
}
getUserMedia({
audio: false,
video: {
mandatory: {
minWidth: 500,
minHeight: 300,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id}]
}
}, function(stream) {
console.log("dddd", stream);
callback(stream);
}, logError);
});
}
function logError(error) {
console.log("logError: ", error);
}
let container;
var CanvasTest = React.createClass({
getInitialState: function() {
return {
isFront: true,
selfViewSrc: null};
},
componentDidMount: function() {
container = this;
},
render() {
return (
<View>
<RTCView streamURL={this.state.selfViewSrc} />
{console.log("this.state: ", this.state)}
{getLocalStream(true, function(stream) {
//localStream = stream;
//container.setState({selfViewSrc: stream.toURL()});
})
}
</View>
);
}
});
AppRegistry.registerComponent('CanvasTest', () => CanvasTest);
Everything is okay until I try to call the getLocalStream function. I get an "undefined is not an object" error for that line. (I've commented out the lines inside the callback to see if they are causing the problem, they are not).
This is what I get from the console in Android Studio:
E/ReactNativeJS: undefined is not an object (evaluating 'WebRTCModule.mediaStreamTrackGetSources')
E/EGL_emulation: tid 3106: eglSurfaceAttrib(1165): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xa0899300, error=EGL_BAD_MATCH
I think I'm calling the function in the wrong place. I want the view to load up the camera stream when the app starts. What am I doing wrong?
Is there a simpler example somewhere of using WebRTC in react native?
About undefined is not an object
It may because of not install it properly.
I'd suggest restart a fresh build again:
remove npm module: rm -rf $YourProject/node_modules/react-native-webrtc
clean npm cache: npm cache clean
clear gradle build intermediate files or
clear xocde project by Product -> clean
( it depends on your env )
npm install react-native-webrtc
follow the documents steps by steps carefully (Android / iOS)
be sure grant all permissions mentions on documents then try again.
Where to execute getLocalStream()
in your case, you can execute it in ComponentDidMount
otherwise, in some case, app may warn that you can't setState() in render()
(setState() will trigger render() normally, the warning is to prevent infinite loop.)
Suggestion
I would suggest you to NOT test it on simulators as possible for libraries which needs to access lots of hardware's functionalities.