React native error: [Unhandled promise rejection: TypeError: _app.default.storage is not a function.] - react-native

I'm using react native, expo and firebase to develop my app. I'm having trouble trying to upload an image to firebase storage.
I will show some of my imports and code here. I have my firebase configuration file set up like so:
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
const firebaseConfig = {
apiKey: "**",
authDomain: "**",
projectId: ""**"",
storageBucket: "**",
messagingSenderId: "**",
appId: "**",
measurementId: "**"
};
let app;
if (firebase.apps.length === 0) {
app = firebase.initializeApp(firebaseConfig)
} else {
app = firebase.app();
}
const db = app.firestore();
const auth = firebase.auth();
export { db, auth, firebaseConfig};
Inside my register file I have the following imports:
import * as ImagePicker from 'expo-image-picker';
// firebase
import firebase from 'firebase/compat/app';
import { auth, db, firebaseConfig } from '../config/Firebase';
// image storage
import storage from 'firebase/storage';
Then, I try and upload the image to firestore using the following functions:
let openImagePickerAsync = async () => {
let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
alert('Permission to access camera roll is required!');
return;
}
let pickerResult = await ImagePicker.launchImageLibraryAsync();
if (pickerResult.cancelled === true) {
return;
}
setImage(pickerResult.uri);
}
const uploadImage = async () => {
const imageUri = image;
let filename = imageUri.substring(imageUri.lastIndexOf('/') + 1);
try {
await storage().ref(filename).putFile(imageUri);
console.log('Image uploaded!');
} catch (error) {
console.log(error);
}
}
The error I'm receiving is: "0, _storage.default) is not a function." Can anyone help?

Related

null is not an object (evaluating 'LoginManager.logInWithPermissions')

When I try to login to Facebook in expo android app, getting the following error
null is not an object (evaluating 'LoginManager.logInWithPermissions')
const SignInwithFB = async () => {
try {
await LoginManager.logInWithPermissions(["public_profile", "email"]);
const data = await AccessToken.getCurrentAccessToken();
if (!data) {
return;
}
const facebookCredential = FacebookAuthProvider.credential(data.accessToken);
const auth = getAuth(firebase);
const response = await signInwithCredential(auth, facebookCredential);
console.log(response);
} catch (e) {
console.log(e);
}
}
installed by following this instructions: https://www.npmjs.com/package/react-native-fbsdk-next
Check Expo installation section in npm install page, make sure you have implemented the instruction
const SignInwithFB = async () => {
try {
const loginManagerResult = await LoginManager.logInWithPermissions(["public_profile", "email"]);
if(loginManagerResult) {
const data = await AccessToken.getCurrentAccessToken();
if (!data) {
return;
}
const facebookCredential = FacebookAuthProvider.credential(data.accessToken);
const auth = getAuth(firebase);
const response = await signInwithCredential(auth, facebookCredential);
console.log(response);
}
} catch (e) {
console.log(e);
}
}

How to call useNavigation inside axios file

I try to implement axios interceptor, for my request.
So when the error response is forbidden (401), I want to clear token and navigate to login screen.
But when I want to call useNavigation from react navigation v5 inside my axios file, it always shows error like this.
React Hook "useNavigation" is called in function "refreshAccessToken" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.
This is my axios file code,
import axios from 'axios'
import AsyncStorage from '#react-native-community/async-storage'
import {useNavigation} from '#react-navigation/native'
import {generateRandomString, getDeviceInfo} from '../helper/helper'
const base = axios.create({
baseURL: '------',
timeout: 500000,
headers: {
'Content-Type': 'application/json'
}
})
async function refreshAccessToken() {
const navigation = useNavigation()
try {
const refreshToken = await AsyncStorage.getItem('refreshToken')
const response = await base.get('------', {
refreshToken
})
await AsyncStorage.setItem('accessToken', response.data.accessToken)
console.log('Response from refresh access token ', response)
return Promise.resolve(response.data)
} catch (error) {
console.log('Error from refresh access token', error.response)
if (error.response.data.errors.flag === 'INVALID_REFRESH_TOKEN') {
await AsyncStorage.removeItem('refreshToken')
await AsyncStorage.removeItem('accessToken')
}
return Promise.reject(error)
}
}
base.interceptors.request.use(
async function (config) {
const accessToken = await AsyncStorage.getItem('accessToken')
config.headers.authorization = accessToken
const deviceInfo = await getDeviceInfo()
const latitude = await AsyncStorage.getItem('latitude')
const longitude = await AsyncStorage.getItem('longitude')
config.headers['accept-language'] = 'id-ID'
config.headers['version'] = '1.0.0'
config.headers['date'] = new Date().toUTCString()
config.headers['x-coordinate'] = `${latitude};${longitude}`
config.headers['x-trace-id'] = generateRandomString()
config.headers['x-device'] = `${deviceInfo.deviceType}/${deviceInfo.deviceName}/${deviceInfo.deviceVersion}/${deviceInfo.deviceUid}`
return config
},
function (error) {
return Promise.reject(error)
}
)
base.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
if (error.response.status === 403 && !originalRequest._retry) {
originalRequest._retry = true
const accessToken = await refreshAccessToken()
originalRequest.headers.Authorization = accessToken
return axios(originalRequest)
}
return Promise.reject(error)
}
)
export default base
You can't, hooks are only meant to be called inside components. There is a guide on how to navigate without the navigation prop you could use for this situation though.
You could also send an event (via a custom event emitter) and set up a listener anywhere else in your app where the navigation prop is available.

How can i navigate to homescreen after facebook authentication using firebase + expo

Hello I'm new to react native and I'm trying to navigate to Home Screen with a successful authentication, but this generates an error, can someone help me? please
loginWithFacebook = async() => {
await Facebook.initializeAsync(
'235487284376992',
);
const { type, token } = await Facebook.logInWithReadPermissionsAsync(
{ permissions: ['public_profile'] }
);
if (type === 'success') {
const credential = firebase.auth.FacebookAuthProvider.credential(token);
this.props.navigation.navigate('Home')
firebase
.auth().signInWithCredential(credential).catch(error => {
console.log(error);
});
}
Firebase is working, however an error is generated during navigation
The error when try login
this error only happens after the first authentication, then the navigation normally occurs
Are you using react-native-firebase?
Which version are you using?
If you are using react-native-firebase v6+ , you need to install #react-native-firebase/auth module.
React Native Firebase version 6 has been re-created from the ground up.
And also, you must import the firebase from auth module on header
import {firebase} from "#react-native-firebase/auth";
This is my code.
import {
createTypes,
createAction,
transformNetworkError,
socialLoginError,
} from '../../utils/actions';
import {getWithData} from '../../utils/request';
import {OneSignalUtils} from '../../utils/oneSignalUtils';
import {FirebaseUtils} from '../../utils/firebaseServices';
import { LoginManager, AccessToken } from 'react-native-fbsdk';
import { GoogleSignin } from '#react-native-community/google-signin';
import {firebase} from "#react-native-firebase/auth";
const facebookLogin = () => async dispatch => {
const loginAction = {
do: () => createAction(LOGIN.DO, {}),
success: (response, authData) => createAction(LOGIN.SUCCESS, {userData: response, authData: authData}),
failed: (error) => createAction(LOGIN.FAILED, error),
};
try {
dispatch(loginAction.do());
const result = await LoginManager.logInWithPermissions(['public_profile', 'email']);
if (result.isCancelled) {
dispatch(loginAction.failed(socialLoginError({status: true, message: 'Facebook login canceled.'})));
}
const logindata = await AccessToken.getCurrentAccessToken();
if (!logindata) {
dispatch(loginAction.failed(socialLoginError({status: true, message: 'Something went wrong obtaining access token.'})));
return null;
} else {
const credential = firebase.auth.FacebookAuthProvider.credential(logindata.accessToken);
const firebaseUserCredential = await firebase.auth().signInWithCredential(credential);
const data = firebaseUserCredential.user.toJSON();
await FirebaseUtils.userRef.doc(data.uid).set(data);
dispatch(loginAction.success());
return data;
}
} catch (e) {
console.log('facebook login error', e);
dispatch(loginAction.failed(socialLoginError({status: true, message: 'Something went wrong.'})));
return null;
}
};

How to upload image to firebase using react native

I need way to upload image to firebase
i tried to use react-native-fetch-blob library
but I think there is something wrong with installing the library
No need to use react-native-fetch-blob. Here is how I do it on my project.
Install both react-native-firebase and react-native-image-picker. Follow the installation steps from their documentation guide.
Then implement 2 small functions to do image pick and upload to firebase. Here is the sample code.
// 1. Import required library
import firebase from 'react-native-firebase';
import ImagePicker from 'react-native-image-picker';
// 2. Create a function to pick the image
const pickImage = () => {
return new Promise((resolve, reject) => {
ImagePicker.showImagePicker(pickerOptions, response => {
if (response.didCancel) return;
if (response.error) {
const message = `An error was occurred: ${response.error}`;
reject(new Error(message));
return;
}
const { path: uri } = response;
resolve(uri);
});
});
};
// 3. Create a function to upload to firebase
const uploadImage = async (fileName, uri) {
return new Promise(
(resolve, reject) => {
firebase
.storage()
.ref(`uploads/${filename}`)
.putFile(uri)
.then(resolve)
.catch(reject);
}
);
}
Then simply firing both function as you need, here is the sample to pick and immediately upload it.
const pickImageAndUpload = async () => {
const uri = await pickImage();
const fileName = 'someImage.jpg';
const { state, downloadURL } = await uploadImage(fileName, uri);
}
async function uploadImageAsync(itemImage, passedParameter, ItemName, ItemDesc, ItemPrice, ItemWeight) {
const response = await fetch(itemImage);
const blob = await response.blob();
console.log("uri of the elements ius", blob)
var storageRef = firebase.storage().ref();
var file = blob
var metadata = {
contentType: 'image/jpeg',
};
const timeStamp = Date.now();
var uploadTask = storageRef.child('CategoryDescription' + "/" + `${passedParameter}` + "/" + `${ItemName}`).put(file, metadata);
//For image pick
pickImage = async () => {
const { CAMERA, CAMERA_ROLL } = Permissions;
const permissions = {
[CAMERA]: await Permissions.askAsync(CAMERA),
[CAMERA_ROLL]: await Permissions.askAsync(CAMERA_ROLL),
};
if (permissions[CAMERA].status === 'granted' && permissions[CAMERA_ROLL].status === 'granted') {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: false,
aspect:[4,3],
quality: 0.5,
});
// console.log(result);
if (!result.cancelled) {
this.setState({ itemImage: result.uri });
}
}

React Native Request failed with status code 400

Does anyone have experience working with this API:
https://authenticjobs.com/api/docs#introduction
I have been running through a few iterations of implementation in my React Native project and I was originally getting this error:
undefined is not an object (evaluating '_ref.longitude')
And now I am getting this error:
Request failed with status code 400
This is the action creator that is attempting to log the data object of this API request.
import axios from "axios";
import reverseGeoCode from "latlng-to-zip";
import qs from "qs";
import { FETCH_JOBS } from "./types";
const JOB_ROOT_URL = "https://authenticjobs.com/api/?";
const JOB_QUERY_PARAMS = {
api_key: "5634cc46389d0d872723b8c46fba672c",
format: "json"
// latlong: 1,
// radius: 10,
// q: "javascript"
};
const buildJobsUrl = zip => {
const query = qs.stringify({ ...JOB_QUERY_PARAMS, l: zip });
return `${JOB_ROOT_URL}${query}`;
};
export const fetchJobs = region => async dispatch => {
try {
let zip = await reverseGeoCode(region);
const url = buildJobsUrl(zip);
let { data } = await axios.get(url);
dispatch({ type: FETCH_JOBS, payload: data });
console.log(data);
} catch (e) {
console.log(e);
}
};
I got it to work with this refactor, although this is going to kind of take my application in a different direction:
import axios from "axios";
import { FETCH_JOBS } from "./types";
const JOB_ROOT_URL = "https://authenticjobs.com/api/?api_key=";
const JOB_QUERY_PARAMS = {
key: "a446a0eefe6f5699283g34f4d5b51fa0",
method: "aj.jobs.getLocations",
format: "json",
category: "javascript"
};
export const fetchJobs = region => async dispatch => {
try {
const url =
JOB_ROOT_URL +
JOB_QUERY_PARAMS.key +
"&method=" +
JOB_QUERY_PARAMS.method +
"&category=" +
JOB_QUERY_PARAMS.category +
"&format=" +
JOB_QUERY_PARAMS.format;
let { data } = await axios.get(url);
dispatch({ type: FETCH_JOBS, payload: data });
console.log(data);
} catch (e) {
console.log(e);
}
};