I am following the react native firebase docs (https://rnfirebase.io/docs/v5.x.x/auth/phone-auth) on Phone Authorization and am confused about the need (or no need) for reCAPTCHA.
The docs do not pass a second parameter to the signInWithPhoneNumber() method but when calling the method I receive an error asking for the recaptchaVerifier as the second parameter. Because I am writing the app for both iOs and Android I utilized the Web connection to Firebase and am not using the generated JSON file. I believe this is my issue as it thinks I am calling the API from a non-mobile device.
Is Firebase Web the best way to connect a React Native cross platform application? If it is, is there a way to generate the reCAPTCHA code?
The firebase docs talk about an invisible reCAPTCHA but they only provide code for HTML with a button ID and whatnot. (I did try to give and an ID as a prop but found no success) https://firebase.google.com/docs/auth/web/phone-auth
My config file:
import firebase from 'firebase';
class Config {
constructor() {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: "AIaskdjf93rlaksdjf99999",
authDomain: "myDomain.firebaseapp.com",
databaseURL: "https://myDomain.firebaseio.com",
projectId: "myDomain",
storageBucket: "",
messagingSenderId: "88827277272",
appId: "somenumbersomitted",
measurementId: "akjdsfkljad"
});
}
}
login = async (user, success_callback, failed_callback) => {
await firebase
.auth()
.signInWithEmailAndPassword(user.userName, user.password)
.then(success_callback, failed_callback);
};
//todo:: need to update signInWithPhoneNumber second param to be the recaptcha token
loginWithPhone = async (phoneNumber, success_callback, failed_callback) => {
var applicationVerifier = ?????;
await firebase
.auth()
.signInWithPhoneNumber(phoneNumber, applicationVerifier)
.then(success_callback, failed_callback);
};
//todo: figure out how to get this method to work in RN. Not able to take in button ID...
recaptchaVerifier = async (phoneNumber, success_callback, failed_callback) =>{
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': function(response) {
loginWithPhone(phoneNumber, success_callback, failed_callback);
}
});
};
}
const config = new Config();
export default config;
I managed to get phone number authentication working on React Native by using https://rnfirebase.io/ and the following code:
const sendSmsCode = async (phoneNumber: string) => {
const isUserPhoneNumberLinked = await getIsUserPhoneNumberLinked(
phoneNumber
);
if (!isUserPhoneNumberLinked) {
} else {
try {
let confirmationResult = await firebase
.auth()
.signInWithPhoneNumber(phoneNumber, true);
Promise.resolve();
setIsSmsCodeSent(true);
confirmationRef.current = confirmationResult;
} catch (error) {
throw error;
}
}
};
And then you can use confirmationRef.current.confirm() to confirm the sms code:
const verifySmsCode = async () => {
const result = await confirmationRef.current.confirm(smsCode);
if (result.user) {
dispatch(authenticatedUserAction());
}
};
Related
I am currently setting up push notifications on my react/firebase project.
I have followed all the steps and added the firebase-messaging-sw.js, getToken etc..
I used to be able to get a FCM token back from getToken but I am no longer able to do so due to this error message:
An error occurred while retrieving token. FirebaseError: Messaging:
A problem occurred while subscribing the user to FCM: Request contains an invalid argument.
(messaging/token-subscribe-failed).
at requestGetToken (requests.ts:67:1)
at async getNewToken (token-manager.ts:139:1)
This error occurs when I call the getTokenFound() method
Before when this was working, I would also have problems with the service worker if I was running the same project on a different system. Only my main development system was able to not hit the service worker error:
An error occurred while retrieving token. FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope
('http://localhost:3000/firebase-cloud-messaging-push-scope%27) with script
('http://localhost:3000/firebase-messaging-sw.js%27): ServiceWorker script evaluation failed
(messaging/failed-service-worker-registration).
Two two issues seem to be persistent, often it seems like an error loop happens if I deny the notification permissions and then try to allow them again, I would get the invalid argument error.
Here are my relevant code blocks below, I'm really not sure what else to change here. The react setup for push notifications seems very inconsistent depending on what machine Im on. Many thanks for any insight!
firebase-messaging-sw.js (in public dir with index.html)
importScripts('https://www.gstatic.com/firebasejs/8.3.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.3.1/firebase-messaging.js');
const firebaseConfig = {
apiKey: DATA,
authDomain: DATA,
databaseURL: DATA,
projectId: DATA,
storageBucket: DATA,
messagingSenderId: DATA,
appId: DATA,
measurementId: DATA
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) {
console.log("Received background message ", payload);
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: "../src/assets/image/default.svg",
tag: "notification-1"
};
return self.registration.showNotification(
notificationTitle,
notificationOptions
);
});
firebase.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getFunctions } from "firebase/functions";
import { getStorage } from "firebase/storage";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
import 'firebase/storage';
export const app = initializeApp({
apiKey: data,
authDomain: data,
databaseURL: data,
projectId: data,
storageBucket: data,
messagingSenderId: data,
appId: data,
measurementId: data
});
export const messaging = getMessaging(app);
export const firestore = getFirestore(app);
export const functions = getFunctions(app);
export const storage = getStorage(app);
export const getTokenFound = async () => {
let currentToken = "";
try {
currentToken = await getToken(messaging, { vapidKey: myVapidKey});
if (currentToken) {
console.log("CURRENT TOKEN", currentToken)
} else {
}
} catch (error) {
console.log("An error occurred while retrieving token. ", error);
}
return currentToken;
};
export const onMessageListener = () =>
new Promise((resolve) => {
onMessage(messaging, (payload) => {
console.log("payload", payload)
resolve(payload);
});
});
I have integrated Firebase in my React code. Push Notifications are displayed in Firefox, the methods onMessage() and onBackgroundMessage() work fine in Firefox but not in Chrome.
I have initialised firebase in my App.js (Main component that loads all the components).
I have included firebase-messaging-sw.js in my public folder. Please let me know if I need to add/subtract anything from my code.
I have tested this code on localhost as well as on a secured domain.
Here is my
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-messaging.js');
firebase.initializeApp({
databaseURL: 'databaseURL.firebaseio.com',
apiKey: "apiKey",
authDomain: "authDomain.firebaseapp.com",
projectId: "projectId",
storageBucket: "storageBucket",
messagingSenderId: "messagingSenderId",
appId: "appId"
});
const initMessaging = firebase.messaging();
initMessaging.onBackgroundMessage(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
// icon: '/firebase-logo.png'
};
self.registration.showNotification(notificationTitle,
notificationOptions);
});
App.js code
import firebase from './firebase';
export class App extends Component {
callFirebase = () => {
try {
const messaging = firebase.messaging();
messaging.requestPermission().then(() => {
return messaging.getToken({ vapidKey: "vapidKey" })
})
.then((token) => {
console.log("Connected To FIREBASE")
console.log("Token: ", token);
this.props.firebaseToken(token);
})
.catch(e => {
this.props.firebaseToken(null);
console.log("Err from firebase", e)
})
messaging.onMessage(function (payload) {
console.log("Message received. ", payload);
// ...
});
}
catch (e) {
console.log("Error from firebase: ", e);
}
}
componentDidMount() {
this.callFirebase();
}
render() {
return (
<Code/>
);
}
}
export default (App);
It can be a Firewall configuration issue, You can try with different internet and if it works then you need to add this configuration to the firewall.
To Receive Notification:
You need open 5228, 5229 and 5230 as per the documentation.
Original Answer: link
I am trying to integrate my react app with Firebase to implement push notifications. I have this file with all configurations inside my src folder :
import firebase from 'firebase/app';
import 'firebase/messaging';
const config = {
apiKey: "API_KEY",
authDomain: "MY_DOMAIN",
databaseURL: "DATABASE_URL",
projectId: "PROJECT_ID",
storageBucket: "STORAGE_BUCKET",
messagingSenderId: "SENDER_ID",
appId: "APP_ID",
measurementId: "MEASURE_ID"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
export const requestFirebaseNotificationPermission = () =>
new Promise((resolve, reject) => {
messaging
.requestPermission()
.then(() => messaging.getToken())
.then((firebaseToken) => {
resolve(firebaseToken);
})
.catch((err) => {
reject(err);
});
});
export const onMessageListener = () =>
new Promise((resolve) => {
messaging.onMessage((payload) => {
resolve(payload);
});
});
And, here is how I implement the function to make push notifications work out inside my App.js :
// Load the FCM configuration parameters and activate the push notifications through the app
requestFirebaseNotificationPermission()
.then((firebaseToken) => {
// eslint-disable-next-line no-console
console.log("CHECK_FCM_TOKEN", firebaseToken);
this.setState({ fcmToken: firebaseToken })
})
.catch((err) => {
return err;
});
This is the error that I always get and I am stuck since long with no solutions at all :
If there could be any help to fix this, I would be thankful.
I had similiar issue. The problem was i was not loading the service worker file properly.
Place your service worker file in public folder and try accessing it.
For eg: my service worker file(firebase-messaging-sw.js) was placed in public folder. So if i open http://localhost:3000/firebase-messaging-sw.js i can view the js file.
Before react was trying to fetch this file and returned an html(default index page) file and caused to return MIME type error.
I am using firebase messaging for web push notification with react. But browser show this message
Messaging: This browser doesn't support the API's required to use the firebase SDK. (messaging/unsupported-browser)
This is code :
const initializedFirebaseApp = firebase.initializeApp({
apiKey: "XXXXXX",
authDomain: "XXXXXXX",
databaseURL: "XXXXXXXXX",
projectId: "XXXXXX",
storageBucket: "XXXX",
messagingSenderId: "XXXXXX",
appId: "XXXXXX"
});
if (firebase.messaging.isSupported()) {
let messaging = initializedFirebaseApp.messaging();
}
firebase.messaging.isSupported() is always returning the false. Is there any way I should proceed?
Version for react : 16.8.2 and firebase version : 6.0.2
FCM supports only in localhost and the https enabled sites only. if you want FCM to support you need to either work on localhost or deploy somewhere (you can use firebase).
If you are using proxy using nginx like local.somehost.com cloud messaging doesn't support. To solve this you need to make your local.somehost.com as HTTPS you can install openssl and certificate and key in your nginx.
I think this solves your problem.
In addition to the above explanation you can check if the browser supports messaging by doing:
const messaging = firebase.messaging.isSupported() ? firebase.messaging() : null
isSupported() in version 9
return Promise so you should wait for resolving
const messaging = (async () => {
try {
const isSupportedBrowser = await isSupported();
if (isSupportedBrowser) {
return getMessaging(config);
}
console.log('Firebase not supported this browser');
return null;
} catch (err) {
console.log(err);
return null;
}
})();
If you are using version 9 you should pass messaging to (onMessageListener resolver and getToken )
onMessageListener
export const onMessageListener = async () =>
new Promise((resolve) =>
(async () => {
const messagingResolve = await messaging;
onMessage(messagingResolve, (payload) => {
// console.log('On message: ', messaging, payload);
resolve(payload);
});
})()
);
getToken
export const requestForToken = async (dispatch) => {
try {
const messagingResolve = await messaging;
const currentToken = await getToken(messagingResolve, {
vapidKey: *your FCM APP SERVER KEY*,
});
if (currentToken) {
*your code*
}
} catch (err) {
console.log('An error occurred while retrieving token. ', err);
}
};
I used dynamic imports for solving this issue so that the file is not even evaluated before the feature is detected. I am using firebase SDK 8.2.0.
This is how my useEffect function looks like on the top level of my app.
import { isSupported } from "firebase/messaging";
useEffect(() => {
(async () => {
const hasFirebaseMessagingSupport = await isSupported();
if (hasFirebaseMessagingSupport) {
const { requestForToken } = await import("./api/cloud-notification/firebase");
await requestForToken();
}
})();
}, []);
This is how my firebase connection file looks like ("./api/cloud-notification/firebase"):
import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";
const FIREBASE_VAPID_KEY = "your-firebase-public-vapid-key";
const firebaseConfig = {
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
};
initializeApp(firebaseConfig);
const messaging = getMessaging();
const getFirebaseToken = async () => {
try {
const currentToken = await getToken(messaging, { vapidKey: FIREBASE_VAPID_KEY });
if (!currentToken) {
console.log("No registration token available. Request permission to generate one.");
}
} catch (error) {
console.log("An error occurred while retrieving token. ", error);
}
};
export const requestForToken = async () => {
try {
const permission = await Notification.requestPermission();
if (permission === "granted") {
await getFirebaseToken();
}
} catch (error) {
console.log("An error occurred while getting user permission. ", error);
}
};
i want to use facebook login in my react native app.. i used firebase on web (reactJs ).. now i use same method for react native app but its not working...
i want fbSignin button which allow me to use user profile pic and name etc..
here is my code..
import React, { Component } from "react"
import { Container, Item, Button, Text } from "native-base"
import * as firebase from "firebase"
import { FBLogin, FBLoginManager } from "react-native-facebook-login"
// Initialize Firebase
var config = {
apiKey: "AIzaSyAK7dr25d-qnsHCdvkeoVPWs7Q0",
authDomain: "quiz-appasdn-ba8c1.firebaseapp.com",
databaseURL: "httpsasdasdasdasd-ba8c1.firebaseio.com",
projectId: "quiz-asdaasdasdc1",
storageBucket: "pplicationasdasd-asddappspot.com",
messagingSenderId: "23764257465237"
};
firebase.initializeApp(config);
var provider = new firebase.auth.FacebookAuthProvider();
class App extends Component {
fbLogin() {
firebase.auth().signInWithPopup(provider).then(function (result) {
var token = result.credential.accessToken;
var user = result.user;
}).catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
});
}
render() {
return (
<Button onPress={this.fbLogin.bind(this)}>
<Text>faacebook Login</Text>
</Button>
);
}
};
export default App
thanks in advance..
firebase.auth().signInWithPopup(provider) doesn't work for react-native you have to use firebase.auth().signInAndRetrieveDataWithCredential(credential) along with the react-native-fbsdk to sign in with facebook..
here is the snippet
<LoginButton
onLoginFinished={
(error, result) => {
if (error) {
alert("login has error: " + result.error);
} else if (result.isCancelled) {
alert("login is cancelled.");
} else {
AccessToken.getCurrentAccessToken().then(
(data) => {
const provider = firebase.auth.FacebookAuthProvider;
const credential = provider.credential(data.accessToken.toString());
firebase.auth().signInAndRetrieveDataWithCredential(credential)
.then(function(userCredential) {
console.log(JSON.stringify(userCredential));
});
}
)
}
}
}
onLogoutFinished={() => alert("logout.")}/>
Resources :
Facebook React Native SDK
Firebase signInAndRetrieveDataWithCredential
i just know lib react native to use login facebook https://developers.facebook.com/docs/react-native/login mybe this can help you :)