(RN) Possible Unhandled Promise Rejection (id: 0): Push Notification - firebase

I'm new to React Native. I am sending a link to the app with "push notification". When I tested it, everything works both in the background and when the application is closed. But every time I open the application, I get the following warning. How can I resolve this situation?
WARN Possible Unhandled Promise Rejection (id: 0):
TypeError: null is not an object (evaluating 'remoteMessage.data')
My codes:
import React, { useEffect } from 'react'
import { Button, Linking, View } from 'react-native'
import styles from './styles/SplashStyles'
import messaging from '#react-native-firebase/messaging'
import { DASHBOARD } from '../navigation/routesNames'
const Splash = ({ navigation }) => {
useEffect(async () => {
messaging()
.subscribeToTopic('users')
.then(() => console.log('Subscribed to topic!'));
//Notification caused app to open from background state:'
messaging()
.onNotificationOpenedApp(remoteMessage => {
if (remoteMessage.data.url) {
Linking.openURL(remoteMessage.data.url)
}
});
//Notification caused app to open from quit state
messaging()
.getInitialNotification()
.then(remoteMessage => {
if (remoteMessage.data.url) {
Linking.openURL(remoteMessage.data.url)
}
});
}, [])
return (
<View style={styles.container}>
<Button
title={"Start"}
onPress={() => {
navigation.reset({
index: 0,
routes: [{ name: DASHBOARD }]
})
}}
/>
</View>
)
}
export default Splash

I think it is because at initialization, the value for remoteMessage is not yet defined when it is rendered specifically via remoteMessage.data, causing the error. If you don't mind introducing a dependency on the lodash package, there's a helper called 'has' that checks if path exists. For example:
if (_.has(remoteMessage, 'data.url') { ....

Related

React Native + Api Entity (ASP.Net) - JSON Parse Error: Unrecognized Token

I am new using native react, I am developing a project that consists in showing the data of an Api in my project. I have seen tutorials and most, if not all, use the same Api:
But what I want is to be able to show the data of a local API that connects to a local BD as well, which is why I developed a Web API with ASP.Net, I was guided by this
Create a DB in SQL Server (which is the DB that I want to use for this project) and generate the API; the API works correctly, tested with POSTMAN.
Now the problem is that I want to use it in my project, and following the tutorial that is on the official page of React Native in the section does not work for me.
This is my code:
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
componentDidMount(){
return fetch('http://192.168.2.19:53943/api/users')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.users,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.Name}, {item.Email}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
The error message that I get when I execute my project is THIS
JSON Parse Error: Unrecognized Token
What could I be doing wrong? I suspect that it may be the URL that happened to the FETCH, since it eliminates all of the render () and only leaves a showing a message and the same error keeps coming up. Thank you
hi you shuld add this code in Global.asax Application_Start() :
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
and add this code in WebApiConigg :
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
rest visual stdio and run again project WebApi address
stop react-native emulator => cntrl+ c react-native-run-android

"Callback URL does not contain state" error from Firebase with Facebook Auth and React Native

I'm attempting to write a React Native app using Firebase and Facebook Auth. Here is the complete app code:
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { LoginManager, AccessToken, LoginButton } from 'react-native-fbsdk';
import * as f from './config/firebase';
export default class App extends React.Component {
fbLoginHandler(error, result) {
if (error) {
alert('Login failed with error: ' + error);
} else if (result && result.isCancelled) {
alert('Login cancelled');
} else {
AccessToken.getCurrentAccessToken().then((accessTokenData) => {
const credential = f.provider.credential(accessTokenData.accessToken);
f.auth.signInAndRetrieveDataWithCredential(credential).then((s) => {
alert('Success! ' + s);
}, (signinError) => {
console.log('Signin error', signinError);
alert('Signin error' + signinError);
});
}, (tokenError) => {
alert('Some error occurred' + tokenError);
});
}
}
render () {
return (
<View style={styles.container}>
<LoginButton
readPermissions={['public_profile', 'email']}
onLoginFinished={(error, result) => this.fbLoginHandler(error, result)}
onLogoutFinished={() => alert('logout.')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
}
});
This is my Firebase config file (the './config/firebase' import in the above snippet):
import * as firebase from 'firebase';
const config = {
apiKey: <api key>,
authDomain: <auth domain>,
databaseURL: <database URL>,
projectId: <project ID>,
storageBucket: <storage bucket>,
messagingSenderId: <messaging sender ID>
};
firebase.initializeApp(config);
export const database = firebase.database();
export const auth = firebase.auth();
export const provider = new firebase.auth.FacebookAuthProvider();
I have entered the required OAuth redirect URI on my Facebook console, as instructed in the Firebase documentation. I've also added a few others based on suggestions found in other Stack Overflow threads. The redirect URIs I'm authorizing are:
https://<MyAppID>.firebaseapp.com/__/auth/handler
https://auth.firebase.com/auth/facebook/callback
https://auth.firebase.com/v2/<MyAppID>/auth/facebook/callback
https://localhost/
http://localhost/
The auth process gets part of the way there (I can see on my Facebook console that a user has been authenticated) but signInAndRetrieveDataWithCredential(credential) returns an error:
{
code: "auth/internal-error",
message: {
error:{
code:400,
message:"Callback URL does not contain state: http://localhost?id_token=<token>&providerId=facebook.com",
errors:[{
message:"Callback URL does not contain state: http://localhost?id_token=<token>&providerId=facebook.com",
domain:"global",
reason:"invalid"
}]
}}
}
}
I have searched the internet, the Facebook developer documentation, the Firebase documentation, and of course Stack Overflow, but I can't find any reference to this specific error anywhere. I believe the error - despite being returned from a Firebase function - is simply being passed through from the Facebook Auth API, but I am not even 100% sure about that.
My assumption is that I must have an incorrect config setting in either Facebook or Firebase, but I've already tried altering the obvious ones (e.g. the redirect URIs, all the OAuth option toggles, etc.) with no change in the error message.
Any insights would be greatly appreciated!
Although I still am not able to diagnose this specific error, I found an effective solution by using the third party react-native-firebase package in place of Google's firebase package:
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { LoginManager, AccessToken, LoginButton } from 'react-native-fbsdk';
import firebase from 'react-native-firebase';
export default class App extends React.Component {
fbLoginHandler(error, result) {
if (error) {
alert('Login failed with error: ' + error);
} else if (result && result.isCancelled) {
alert('Login cancelled');
} else {
AccessToken.getCurrentAccessToken().then((accessTokenData) => {
const credential = firebase.auth.FacebookAuthProvider.credential(accessTokenData.accessToken);
firebase.auth().signInAndRetrieveDataWithCredential(credential).then((s) => {
alert('Success! ' + s);
}, (signinError) => {
console.log('Signin error', signinError);
alert('Signin error' + signinError);
});
}, (tokenError) => {
alert('Some error occurred' + tokenError);
});
}
}
render () {
return (
<View style={styles.container}>
<LoginButton
readPermissions={['public_profile', 'email']}
onLoginFinished={(error, result) => this.fbLoginHandler(error, result)}
onLogoutFinished={() => alert('logout.')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
}
});

React-Redux unable to fetch data from firebase react native

I have created a database in firebase the schema is below:
Now All I have been trying to do is just have it show up when I do a console log but nothing shows up.
Below is the code for my JobsActions.js
import firebase from 'firebase';
import {
JOBS_FETCH_SUCCESS
} from './types';
export const jobsFetch = () => {
return (dispatch) => {
firebase.database().ref('/jobs')
.on('value', snapshot => {
dispatch({ type: JOBS_FETCH_SUCCESS, payload: snapshot.val() });
});
};
};
This is my reducer:
import {
JOBS_FETCH_SUCCESS
} from '../actions/types';
const INITIAL_STATE = {
// jobs: 'RCCA'
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case JOBS_FETCH_SUCCESS:
console.log(action);
return state;
//return action.payload;
default:
return state;
}
};
This is the JobsList
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View, Text } from 'react-native';
import { jobsFetch } from '../actions';
class JobsList extends Component {
componentWillMount() {
this.props.jobsFetch();
}
render() {
return (
<View style={{ paddingTop: 20 }}>
<Text>Hello</Text>
</View>
);
}
}
export default connect(null, { jobsFetch })(JobsList);
I have authentication using firebase and its not a connection to firebase thats an issue, From what I see, it seems like maybe the ref path is wrong in the Actions file?
You main problem here is not with Firebase actually, since I believe everything else is allright, but with React-Redux.
When you are connecting a component to the store, the connect function recieves two functions. The first one (usually called mapStateToProps) recieves the state and returns an object that will be added to the props. In this case, you are not using it, so passing null is a valid decision.
The second one (usually called mapDispatchToProps) receives the dispatch as a parameter and should return an object with the functions that will be inserted to the props that can be used to dispatch new actions. In this case, you are just passing an object as the second parameter of the connect { jobsFetch }.
When you do this.props.jobsFetch(); you are actually returning the function that receives the dispatch, so nothing is actually executed.
Your mapDispatchToProps should be something similar to this
const mapDispatchToProps = dispatch => {
return {
jobsFetch : () => dispatch(jobsFetch())
}
}
export default connect(
null,
mapDispatchToProps
)(JobsList)
Here, I'm assuming that you are in fact using Redux thunk since you are returning a function that receives the dispatch as a parameter in your actions.
As you may see, we first call the jobsFetch() in order to get the function that receives the reducer, and then we dispatch it.
Let me know if this does not work! There may be something else that is not correct, but this is something that should be addressed. Hope it helps!

Login fail with error: TypeError: Cannot read property 'navigation' of undefined

I'd like to activate Facebook login by react native firebase. My purpose is to move to Signin screen to Main Screen.
I use,
react-native: 0.52.2
react-native-firebase: ^3.2.4
react-navigation: ^1.0.0-beta.28
LoginScreen.js
const facebookLogin = () => {
return LoginManager
.logInWithReadPermissions(['public_profile', 'email'])
.then((result) => {
if (!result.isCancelled) {
console.log(`Login success with permissions: ${result.grantedPermissions.toString()}`)
// get the access token
return AccessToken.getCurrentAccessToken()
}
})
.then(data => {
if (data) {
// create a new firebase credential with the token
const credential = firebase.auth.FacebookAuthProvider.credential(data.accessToken)
// login with credential
return firebase.auth().signInAndRetrieveDataWithCredential(credential)
}
})
.then((currentUser) => {
if (currentUser) {
console.log(currentUser);
return this.props.navigation.navigate('Main');
}
})
.catch((error) => {
console.log(`Login fail with error: ${error}`)
})
}
After (currentUser), I added following that.
this.props.navigation.navigate('Main');
But that doesn't work!
I have already set up Router, and that did work at out of Auth Component.
I checked at console.log and that shows me:
Login fail with error: TypeError: Cannot read property 'navigate' of undefined"
So I tried to move const { navigation } = this.props; from Auth Component to other SigninScreen Component. But I can't see successful login.
Thanks for your answer. And I have defined already in Parent component.
I defined navigation here.
class SignInScreen extends React.Component {
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.containerStyle}>
<TouchableOpacity onPress={facebookLogin}>
<Text style={styles.textStyle}>Facebook</Text>
</TouchableOpacity>
</View>
);
}
}
It seems that the navigation object is undefined. Check the parent component to see if navigation is defined before it is passed as props to this component
It could also be due to the way javascript handles the this keyword. see this answer You could try binding the navigate method to the Class by adding
this.navigate = this.props.navigation.navigate.bind(this) inside the constructor,
and change
.then((currentUser) => {
if (currentUser) {
console.log(currentUser);
return this.props.navigation.navigate('Main');
}
to
.then((currentUser) => {
if (currentUser) {
console.log(currentUser);
return this.navigate('Main');
}

How to render properties of objects in React?

Where exactly should I deal with the problem of this component not loading with the desired state?
My render method causes the following error...
Uncaught TypeError: Cannot read property 'email' of undefined
...even though the JSON.stringify line shows me that the email property does (eventually) exist.
The console.log down in mapStateToProps confirms that state loads first without the any user property (thus causing the error).
Behold my naive attempt to resolve this in my constructor method. It's not working.
What is the right way to deal with this situation? Some conditional inside the render method? Tried that too but still no luck.
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import * as actions from '../actions';
class Feature extends Component {
constructor(props){
super(props);
this.state = {
'auth': {
'user':{
email:'',
id:''
}
}
}
}
componentWillMount() {
this.props.fetchMessage(); // puts the user object into state
}
render() {
return (
<div className="feature">
Here is your feature
{JSON.stringify(this.props.user , null, 2)}
{this.props.user.email}
</div>
);
}
}
function mapStateToProps(state) {
console.log('state',state);
return { user: state.auth.user }
}
export default connect(mapStateToProps, actions)(Feature);
/////////// action /////////
export function fetchMessage(){
return function(dispatch){
axios
.get(ROOT_URL, {
headers: {
authorization: localStorage.getItem('token')
}
})
.then((response) => {
dispatch({
type: FETCH_MESSAGE,
payload: response.data.user
})
})
}
}
///////////////// reducer /////////////
var authReducer = (state={}, action) => {
console.log('action.payload',action.payload);
switch(action.type){
case AUTH_USER: return {...state, error: '', authenticated: true};
case UNAUTH_USER: return {...state, error: '', authenticated: false};
case AUTH_ERROR: return {...state, error: action.payload};
case FETCH_MESSAGE: return {...state, user: {
email: action.payload.email,
id: action.payload._id
}};
default: return state;
};
};
So here is what is happening.. You are making a server request for a user object and on success the received object is stored in your redux store. While performing such an action your component is rendered as follows:
You have initiated the request to the server, which means currently there is no user in your store and so the component is rendered with this.props.user undefined.
Your request is successful and the user object is stored in your store. When this happens react-redux will re-render your component with the user object and this.props.user is available in your component.
During the first step since this.props.user is unavailable you are getting an error while accessing this.props.user.email. Although #jpdelatorre 's answer is pretty good, another thing you can do is simply add a check in your render method.
render() {
let user = this.props.user || {};
....
{user.email}
....
}
Redux uses a global state called store that lives outside your component.
Inside your constructor you have a this.state = {...} statement. This is a local state that is only available to the Feature component.
connect from react-redux basically connects the info inside the store to your component props hence called mapStateToProps.
Edit your mapStateToProps to something like...
function mapStateToProps(state) {
const { auth: { user = {} } = {}} = state;
return {
user
}
}
What it does is try to extract the user property from the store and if it doesn't exist yet, set it to empty object. Your error is due to your mapStateToProps accessing the user property that doesn't exist yet. You might want to set a default value as your initialState to avoid this issue.

Resources