I need your help, all looks good but I cannot receive notification on my react-native application.
Actual setup:
In project.xcworkspace, TARGETS > {App Name} > Signing & Capabilities :
Background Modes: Background fetch and Remote notifications enabled
Push Notifications
Firebase Project:
APNs key was added, with KeyId, TeamId
Apple Developer:
Identifier added with Push Notifications enabled
Key added with "Apple Push Notifications service (APNs)"
Profiles > I created a "Provisioning Profile" to try if I have a connection issue(not resolved with this)
Good to know: I actually use the firebase authentification and it works so I don't think it's a GoogleService-Info.plist issue.
App.js
const requestNotificationPermission = async () => {
messaging()
.requestPermission()
.then(authStatus => {
console.log('APNs Status: ', authStatus);
if (
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus == messaging.AuthorizationStatus.PROVISIONAL
) {
messaging()
.getToken()
.then(async (token) => {
await messaging().registerDeviceForRemoteMessages()
.then((result) => {
console.log('Device registered for remote messages: ', result);
});
console.log('Token', token);
});
messaging().onTokenRefresh(token => {
console.log('Refresh Token: ', token)
});
}
})
.catch(err => {
console.log('Error: ', err);
});
}
React.useEffect(() => {
requestNotificationPermission();
const unsubscribe = messaging().onMessage(async remoteMessage => {
Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage));
})
return unsubscribe;
}, [])
Return :
LOG APNs Status: 1
LOG Device registered for remote messages: true
LOG Token fmORQaQ0FUCjnGA1TgXSDi:APA91bFVDMvgkY13Rl-muzI2kOKCJauFcJCVF7sZZxgnuicawTIcvrl73JtNUEruobDfu1igvgVkXobi3gUTvGXD1QMZoOskXUzAEkDJpMgUvug-9KudE6bJl9oBL0tJCc9Eqv0GXfXa
I tried to create a notification from https://console.firebase.google.com/u/0/project/proj-number/messaging
Result: Nothing append on react-native app.
I tried to create a notification from REST
REST Request Setup :
Method: POST
Url : https://fcm.googleapis.com/fcm/send
Headers > Authorization > key={Cloud Messaging > Server Key}
Body :
{
"data": {},
"notification": {
"body": "This is an FCM notification",
"title": "From Postman"
},
"to": "fmORQaQ0FUCjnGA1TgX[...]"
}
Postman Result :
{
"multicast_id": 5211676236934629976,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1660579924324918%fedf4cbefedf4cbe"
}
]
}
React-native result : Nothing append on react-native app.
Resolved:
App.js
const getToken = () => {
messaging()
.getToken()
.then(x => console.log(x))
.catch(e => console.log(e));
};
const registerForRemoteMessages = () => {
messaging()
.registerDeviceForRemoteMessages()
.then(() => {
console.log('Registered');
requestPermissions();
})
.catch(e => console.log(e));
};
const requestPermissions = () => {
messaging()
.requestPermission()
.then((status) => {
if (status === 1) {
console.log('Authorized');
onMessage();
} else {
console.log('Not authorized');
}
})
.catch(e => console.log(e));
};
const onMessage = () => {
messaging()
.onMessage(response => {
console.log(response.data.notification);
});
};
React.useEffect(() => {
getToken();
if (Platform.OS === 'ios') {
registerForRemoteMessages();
} else {
onMessage();
}
const unsubscribe = messaging().onMessage(async remoteMessage => {
Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage));
})
return unsubscribe;
}, [])
Related
I am trying to send notification in react native via rest api. In response i'm getting success :1. The problem here is i'm not getting notification in emulator.
const token = await firebase.messaging().getToken();
console.log("token in sendNotification ",token)
const FIREBASE_API_KEY = "firebaseApiKey";
const message = {
to :token,
notification: {
title: "This is a Notification",
boby: "This is the body of the Notification",
vibrate: 1,
sound: 1,
show_in_foreground: true,
priority: "high",
content_available: true,
}
}
let headers = new Headers({
"Content-Type" : "application/json",
Authorization: "key=" + FIREBASE_API_KEY,
})
try {
let response = await fetch ("https://fcm.googleapis.com/fcm/send",{
method: "POST",
headers,
body: JSON.stringify(message),
})
response = await response.json();
console.log("response ", response);
} catch (error) {
console.log("error ", error);
}
https://firebase.google.com/docs/cloud-messaging/js/receive
You can follow the incoming message documentation
// Handle incoming messages. Called when:
// - a message is received while the app has a focus
// - the user clicks on an app notification created by a service worker
// `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage((payload) => {
console.log('Message received. ', payload);
// ...
});
In useEffect of App.js
import React,{useEffect} from 'react'
import{View,Text} from 'react-native';
async function onDisplayNotification() {
// Create a channel
const channelId = await notifee.createChannel({
id: 'default',
name: 'Default Channel',
});
// Display a notification
await notifee.displayNotification({
title: 'Notification Title',
body: 'Main body content of the notification',
android: {
channelId,
smallIcon: 'ic_launcher', // optional, defaults to 'ic_launcher'.
},
});
}
const App=()=> {
useEffect(() => {
// Assume a message-notification contains a "type" property in the data payload of the screen to open
messaging().onMessage((payload) => {
console.log('Message received. ', payload);
onDisplayNotification();
// ...
});
messaging().onNotificationOpenedApp(remoteMessage => {
console.log(
'Notification caused app to open from background state:',
remoteMessage.notification,
);
alert("Notification");
});
// Check whether an initial notification is available
messaging()
.getInitialNotification()
.then(remoteMessage => {
if (remoteMessage) {
console.log(
'Notification caused app to open from quit state:',
remoteMessage.notification,
);
}
});
}, []);
return (
<View>
</View>
)
}
export default App;
I create a simple interface to send notification using firebase cloud messaging service. It displays notification when I send notification using firebase - console. But when I insert data using my interface to firebase, It is not showing anything. How can I solve this problem.
Future<void> insertItem() async {
final form = formKey.currentState;
form.save();
Firestore.instance.runTransaction((transaction) async {
await transaction.set(Firestore.instance.collection("Notification").document(), {
'User': _user,
'Title': _title,
'Body': _msg,
});
});}
-Insert Data into Firebase Code-
exports.notificationTrigger = functions.firestore
.document("Notification/{notificationId}")
.onCreate((snapshot, context) => {
msgData = snapshot.data();
var userRef = admin.firestore().collection("Token").doc(msgData.User);
return userRef.get().then((doc) => {
if (!doc.exists) {
console.log("No Devices");
} else {
token = doc.data().Token;
var payload = {
notification: {
title: msgData.Title,
body: msgData.Body,
},
data: {
sendername: msgData.Title,
message: msgData.Body,
},
};
return admin
.messaging()
.sendToDevice(token, payload)
.then(() => {
console.log("pushed notification");
})
.catch((err) => {
console.log(err);
});
}
});});
index.js -
I am trying to send notifications from firebase console to my react-native app
I followed the poor documentation here as much as I understand: https://invertase.io/oss/react-native-firebase/v6/messaging/quick-start
I installed #react-native-firebase/app and /messaging and here is my code in component:
componentDidMount() {
this.reqNotifications()
this.checkNotificationPermission()
}
reqNotifications() {
requestNotifications(['alert', 'badge', 'sound']).then(({status, settings}) => {
console.log('NOTIFICATION STATUS' + status)
});
}
async checkNotificationPermission() {
const enabled = await messaging().hasPermission();
if (enabled) {
console.log('APPROVED');
await messaging().registerForRemoteNotifications()
messaging().getToken().then(token => console.log('token: >> ' + token))
} else {
console.log('NOT APPROVED');
}
}
I am requesting permission via react-native-permissions and permission request is
working.
My Apple APNs are OK on Apple and Firebase console
And I am getting my token by getToken() method on the code
succesfully.
But I cant send anything to device from firebase; nothing happening on neither foreground nor background . I tried with-token test and also tried normal but no, nothing happens.
I added this code to componentDidMount:
messaging().onMessage(async remoteMessage => {
console.log('FCM Message Data:', remoteMessage.data);
});
As I understand this subscribes for cloud messages and when I send some cloud message notification from firebase-console, I should get console output; but nothing happens.
I dont know what am I missing but I think there is a big update on this package and most of docs are for previous version and I really stuck here thanks for assist
for rnfirebase.io V6
componentDidMount = async () => {
this.checkNotificationPermission();
await messaging().requestPermission({provisional: true});
await messaging().registerDeviceForRemoteMessages();
await this.getFCMToken();
if (Platform.OS === 'android') {
this.createAndroidNotificationChannel();
}
this.backgroundState();
this.foregroundState();
};
checkNotificationPermission = () => {
firebase
.messaging()
.hasPermission()
.then(enabled => {
if (!enabled) {
this.promptForNotificationPermission();
}
});
};
promptForNotificationPermission = () => {
firebase
.messaging()
.requestPermission({provisional: true})
.then(() => {
console.log('Permission granted.');
})
.catch(() => {
console.log('Permission rejected.');
});
};
createAndroidNotificationChannel() {
const channel = new firebase.notifications.Android.Channel(
'channelId',
'Push Notification',
firebase.notifications.Android.Importance.Max,
).setDescription('Turn on to receive push notification');
firebase.notifications().android.createChannel(channel);
}
foregroundState = () => {
const unsubscribe = messaging().onMessage(async notification => {
console.log('Message handled in the foregroundState!', notification);
});
return unsubscribe;
};
// Register background handler
backgroundState = () => {
messaging().setBackgroundMessageHandler(async notification => {
console.log('Message handled in the background!', notification);
});
};
I am trying to login with phone number with firebase signInWithPhoneNumber() method for login. In which i have checked whether user auth state has been change or not. If user auth is change then login and redirect to home page. but i m getting auth null
onLoginBtnClicked() {
const { contact, password } = this.props;
const error = Validator('password', password) || Validator('contact', contact);
if (error !== null) {
Alert.alert(error);
} else {
console.log('else');
// this.props.loginUser({ contact, password});
const mobileNo = '+91'+contact;
firebase.auth().signInWithPhoneNumber(mobileNo)
.then(data => console.log(data),
firebase.auth().onAuthStateChanged((user) => {
console.log('user'+user);
if (user && !CurrentUser.isFirstTimeUser) {
const userRef = firebase.database().ref(`/users/`);
userRef.on("value", (snapshot) => {
console.log(snapshot.val());
snapshot.forEach(function(item) {
var itemVal = item.val();
if(itemVal.mobile == contact){
NavigationService.navigate('Home');
}
});
}, (errorObject) => {
console.log("The read failed: " + errorObject.code);
});
//NavigationService.navigate('Home');
}
})
)
.catch(error => console(error.message) );
}
}
There are two things to note here
onAuthStateChanged is a listener which listen for the user auth changes.
signInWithPhoneNumber sends the code to the user's phone, you have to confirm it to authenticate the user.
You need to add the listener in the react lifecycle for the component once it is mounted and remove it when it is unmounted
componentDidMount() {
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.setState({ user: user.toJSON() });
} else {
// Reset the state since the user has been logged out
}
});
}
componentWillUnmount() {
if (this.unsubscribe) this.unsubscribe();
}
// Send Message here
firebase.auth().signInWithPhoneNumber(mobileNo)
.then(confirmResult => this.setState({ confirmResult })
.catch(error => // handle the error here)
// Authenticate User typed Code here
const { userCode, confirmResult } = this.state;
if (confirmResult && userCode.length > 0) {
confirmResult.confirm(codeInput)
.then((user) => {
// handle user confirmation here or in the listener
})
.catch(error => // handle the error here)
}
I'm new with react-native-firebase
I want to link the user after login with facebook provider and google provider
I tried all solutions on the internet but any of them worked.
this is my code
const loginUser = await firebase.auth().signInAndRetrieveDataWithEmailAndPassword('test#gmail.com','password888').then(async function(userRecord) {
console.log("Successfully sign in user:", userRecord.user._user);
let user = firebase.auth().currentUser;
console.log('current user ',user)
let linkAndRetrieveDataWithCredential=firebase.auth().currentUser.linkAndRetrieveDataWithCredential(firebase.auth.FacebookAuthProvider.PROVIDER_ID).then(async u=>{
console.log('linkAndRetrieveDataWithCredential u',u)
}).catch(async (e)=>{
console.log('linkAndRetrieveDataWithCredential error',e)
})
console.log('linkAndRetrieveDataWithCredential error',linkAndRetrieveDataWithCredential)
/**/
await firebase.auth().fetchSignInMethodsForEmail('sss#sss.sss')
.then(async providers => {
console.log('login index providers',providers)
}).catch(function(error){
console.log('login index providers error',error)
})
}).catch(async function(error){
console.log('login error',error,error.email)
if(error.code=='auth/user-not-found'){
}else if(error.code=='auth/wrong-password'){
errorMsg=`${L('password')} ${L('notValid')}`
}
if(errorMsg){
if (Platform.OS === 'android') {
ToastAndroid.show(
errorMsg,
ToastAndroid.LONG
)
} else {
Alert.alert(
'',
errorMsg,
[{ text: L('close'), style: 'cancel' }]
)
}
}
console.log("Error sign in user:", error.code);
})
linkAndRetrieveDataWithCredential needs an AuthCredential, in my app I use react-native-fbsdk to get the credential(You’ll need to follow their setup instructions).
This function will prompt the user to log into his facebook account and return an AccessToken, then you get the credential from firebase and finally linkAndRetrieveDataWithCredential.
linkToFacebook = () => {
LoginManager.logInWithReadPermissions(['public_profile', 'email'])
.then((result) => {
if (result.isCancelled) {
return Promise.reject(new Error('The user cancelled the request'))
}
// Retrieve the access token
return AccessToken.getCurrentAccessToken()
})
.then((data) => {
// Create a new Firebase credential with the token
const credential = firebase.auth.FacebookAuthProvider.credential(data.accessToken)
// Link using the credential
return firebase.auth().currentUser.linkAndRetrieveDataWithCredential(credential)
})
.catch((error) => {
const { code, message } = error
window.alert(message)
})
}