Accessing URL to use issues (expo/react native app/firebase) - firebase

In my current app i want the user to pick a photo from their phone and then to use the downloadable url from firebase storage to then add it to my database. Everything works but when a user(when they first time to pick a image) it says
TypeError: Network request failed
code(logic/state/functions):
const [image, setImage] = useState(null);
const [url, setUrl] = useState(null)
async function postImage () {
try {
// No permissions request is necessary for launching the image library
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.canceled) {
imgFirebase()
setImage(result.assets[0].uri); }
}
catch(E) {
Alert.alert(
"Alert Title",
"My Alert Msg 1",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", onPress: () => console.log("OK Pressed") }
]
);
}
}
async function imgFirebase () {
try {
console.log(image);
const d = await fetch(image)
const dd = await d.blob()
const fileName = image.substring(image.lastIndexOf("/")+1)
const storage = getStorage();
const storageRef = ref(storage, fileName);
uploadBytes(storageRef,dd).then((snapshot) => {
getDownloadURL(snapshot.ref).then(async (url) => {
// Create a query against the collection.
setUrl(url)
console.log(url)
}).catch(e=>{
Alert.alert(
"Alert Title",
"My Alert Msg 2",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", onPress: () => console.log("OK Pressed") }
]
);
})
});
}
catch(e) {
alert(e)
}
}
code(for rendered UI):
<Pressable color="#000" style={{marginTop:20,backgroundColor:"#FF35F0",padding:10,borderRadius:11,color:"#000"}} onPress={postImage}>
<Text style={{color:"#fff",textAlign:"center",fontSize:20}}>Pick Image</Text>
</Pressable>
whats also weird is that after the first time getting this error and then trying to pick a image the error finally goes away. Why does this error come up at first? How would i fix this?

Related

react-native-push-notification's configure method is not return data. Data is coming null . How can i fix it?

react-native-push-notification's configure method is not return data. Data is coming null .Here is my code
React.useEffect(() => {
PushNotification.configure({
onNotification(notification) {
if (notification.userInteraction) {
console.log(notification);
console.log('hi');
}
var nottype = notification.data.actionId;
var notid = notification.data.id;
console.log(notid);
AsyncStorage.setItem('actionId', nottype);
AsyncStorage.setItem('orderId', notid);
},
});
}, []);
you are using react-native-push-notification this library is not the best to handle notification. instead you can use #notifee/react-native to configure this for notification. this is very easy to use and do not need native code configuration.
to create a group or single channel
// Create a group
await notifee.createChannelGroup({
id: 'personal',
name: 'Personal',
});
// Assign the group to the channel
await notifee.createChannel({
id: 'comments',
name: 'New Comments',
groupId: 'personal',
});
here is a sample
import notifee, {
AndroidBadgeIconType,
EventType,
TriggerType,
} from '#notifee/react-native';
const onDisplayNotification = async (item, distance, message) => {
try {
await notifee.requestPermission();
const channelId = await notifee.createChannel({
id: 'default',
name: 'Default Channel',
});
await notifee.displayNotification({
title: `You are getting ${message} ${
message == 'Close' ? 'to' : 'from'
} ${item.name}`,
body: `You are ${distance} M away form ${item.name}`,
android: {
channelId,
actions: [
{
title: 'Close',
pressAction: {
id: 'stop',
},
},
],
smallIcon: 'ic_launcher',
pressAction: {
id: 'default',
},
},
});
} catch (e) {
console.error(e, 'ERRORORORORORORO');
}
};
here is the event with which you can interreact with them .
useEffect(() => {
return notifee.onForegroundEvent(({ type, detail }) => {
switch (type) {
case EventType.DISMISSED:
console.log('User dismissed notification', detail.notification);
break;
case EventType.PRESS:
console.log('User pressed notification', detail.notification);
break;
}
});
}, []);

How to mutation store state in build query redux toolkit

Created an initialState and will be updated the totalPage and currentPage after got the users list.
I found out onQueryStarted from docs, it able to update the store state in this method but only look like only for builder.mutation.
what's the correct way to get the user list and update the store page value in redux toolkit?
Listing two part of the code below:
apiSlice
component to use the hook
// 1. apiSlice
const usersAdapter = createEntityAdapter({})
export const initialState = usersAdapter.getInitialState({
totalPage: 0,
currentPage: 0,
})
export const usersApiSlice = apiSlice.injectEndpoints({
endpoints: (builder) => ({
getUsers: builder.query({ // <--- the docs are using builder.mutation, but i needed to pass params
query: (args) => {
const { page, limit } = args;
return {
url: `/api/users`,
method: "GET",
params: { page, limit },
}
},
validateStatus: (response, result) => {
return response.status === 200 && !result.isError
},
transformResponse: (responseData) => { // <<-- return { totalPages: 10, currentPage: 1, users: [{}] }
const loadedUsers = responseData?.users.map((user) => user)
return usersAdapter.setAll(initialState, loadedUsers)
},
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
try {
const { data } = await queryFulfilled
const {totalPages, currentPage} = data; <----- totalPages & currentPage values are still 0 as initialState
dispatch(setPages({ currentPage, totalPages }))
} catch (error) {
console.error("User Error: ", error)
}
},
providesTags: (result, error, arg) => {
if (result?.ids) {
return [
{ type: "User", id: "LIST" },
...result.ids.map((id) => ({ type: "User", id })),
]
} else return [{ type: "User", id: "LIST" }]
},
})
})
});
export const {
useGetUsersQuery,
} = usersApiSlice
component to use the hook
Try to use the hook in user landing page
const UsersList = () => {
const { data: users, isLoading, isSuccess, isError } = useGetUsersQuery({page: 1, limit: 10 })
return (
<div>return the users data</div>
)
}
update the store value after get the data return

React Native Pressable has to be clicked twice to be executed

I am using react native and firebase v9. When I click to add a chatroom, an alert prompt pops up, the user enters a room name and firebase should automatically roll it out to the UI. But what happens is when the modal is closed, I then have to click the add button again and then the chat room will roll out. How can I fix this so when the user enters a name, presses ok it automatically shows on the UI? Thanks!
My state:
const [rooms, setRooms] = useState([]);
const [input, setInput] = useState("");
Here is my JSX:
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<Pressable onPress={handleAddRoom}>
<View style={styles.addRoom}>
<MaterialCommunityIcons
name="plus-circle"
color="black"
size={42}
/>
<Text style={styles.nameText}>Add</Text>
</View>
</Pressable>
Here are my functions for uploading to firebasev9:
const handleAddRoom = () => {
Alert.prompt("Add New Chat Room", "Please enter a name", [
{ text: "CANCEL", onPress: null },
{ text: "OK", onPress: (text) => setInput(text) },
]);
if (input) {
const colRef = collection(db, "rooms");
addDoc(colRef, {
image: inputData,
roomName: input,
});
}
setInput("");
};
const fetchRooms = async () => {
try {
const colRef = query(collection(db, "rooms"), orderBy("roomName", "asc"));
onSnapshot(colRef, (snapshot) => {
setRooms(
snapshot.docs.map((doc) => ({
id: doc.id,
roomName: doc.data().roomName,
image: doc.data().image,
}))
);
});
} catch (err) {
console.log(err);
}
};
useEffect(() => {
fetchRooms();
}, []);

Inside foreach loop, the await is not working

Below this code downloadcontroller.js
// Retrieve all downloads from the database.
exports.findAll = async (req, res) => {
downloadObj
.findAll(
{
include: [
{
model: composerObj,
required: false,
},
{
model: raagaObj,
required: false,
},
{
model: taalaObj,
required: false,
},
],
where: req.query,
raw:true,
nest: true,
})
.then((data) => {
data.forEach(async (element) => {
const artistsArray = [];
let whereConstraint = {};
JSON.parse(element.artists).forEach( async (ele) => {
artistsArray.push(ele.artistId);
});;
whereConstraint = {
id : {
[Op.in]: artistsArray
}
}
element.Active = "true11";
const artistData = artistService.customfindAll(whereConstraint);
element.artistData = artistData;
console.log("artistData",artistData);
});
console.log("data",data);
console.log("3");
res.status(200).send({
status:200,
message: "ok",
data:data
});
console.log("4");
})
.catch((err) => {
res.status(500).send({
status:500,
message:
err.message || "Some error occurred while retrieving Download.",
});
});
};
Below this code, artistServer.js file
exports.customfindAll = async (whereConstraint) => {
return new Promise(function(resolve, reject) {
artistObj
.findAll({
attributes:{
include: [
[fn('IF',literal('imagePath!=""'),(fn('CONCAT', artistImagePath, 'artist/', col('imagePath'))),artistImageDefaultPath), 'imageFullPath'],
],
},
where: whereConstraint,
order: [
['artistName', 'ASC'],
],
raw:true,
nest: true,
})
.then((data) => {
resolve(data);
});
});
}
Here my problem is
const artistData = artistService.customfindAll(whereConstraint);
not waiting for the data. .So that I got the result, below have mentioned. Actually the artistData attribute column, need result data.
{
"status": 200,
"message": "ok",
"data": [
{
"id": 1,
"fileType": "1",
"customFileName": "test filename",
"artists": "[{\"artistId\":1},{\"artistId\":4},{\"artistId\":2}]",
"accompanyingArtists": "[{\"instrumentId\":1,\"accompanyingArtistId\":1},{\"instrumentId\":2,\"accompanyingArtistId\":6},{\"instrumentId\":3,\"accompanyingArtistId\":4}]",
"Active": "true11",
"artistData": {}
},
{
"id": 2,
"fileType": "1",
"customFileName": "new file name",
"artists": "[{\"artistId\":1},{\"artistId\":4},{\"artistId\":2},{\"artistId\":6},{\"artistId\":3}]",
"accompanyingArtists": "[{\"instrumentId\":1,\"accompanyingArtistId\":1},{\"instrumentId\":2,\"accompanyingArtistId\":6},{\"instrumentId\":3,\"accompanyingArtistId\":4},{\"instrumentId\":3,\"accompanyingArtistId\":3},{\"instrumentId\":4,\"accompanyingArtistId\":2}]",
"Active": "true11",
"artistData": {}
}
]
}
In console page, I artistdata attribute pending...
enter image description here
The customFindAll function returns a Promise but the forEach does not wait for it. Add an await:
const artistData = await artistService.customfindAll(whereConstraint);
Also, forEach does not wait, it just fires off the async functions and move on. To wait for the forEach to finish, you need a map and a Promise.all, like this:
await Promise.all(data.map(async (element) => {
const artistsArray = [];
let whereConstraint = {};
JSON.parse(element.artists).forEach( async (ele) => {
artistsArray.push(ele.artistId);
});;
whereConstraint = {
id : {
[Op.in]: artistsArray
}
}
element.Active = "true11";
const artistData = await artistService.customfindAll(whereConstraint);
element.artistData = artistData;
console.log("artistData",artistData);
}));
The way it works this way is that data.forEach(async (e) => ... runs the async function and discards the results (the Promises). If you use a map, like data.map(async (e) => ..., you'll get an array of Promises, then use await Promise.all(...) to wait for them.

Hooks can only be called inside the body of a function component

I'm trying to implement Firebase Notification in my RN App. I followed this post
But when I run the code, I'm getting Hooks can only be called inside the body of a function component. There's my App.json file
export default class App extends Component {
state = {
isLoadingComplete: false,
};
render() {
return (
<SafeAreaView forceInset={{ bottom: 'never'}} style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<Provider store={store}>
<AppNavigator/>
</Provider>
</SafeAreaView>
);
}
And functions to get the token, permissions and show alert with the remote notification. Are these functions in right place?
useEffect(() => {
this.checkPermission();
this.messageListener();
}, []);
checkPermission = async () => {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
this.getFcmToken();
} else {
this.requestPermission();
}
}
getFcmToken = async () => {
const fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
console.log(fcmToken);
this.showAlert("Your Firebase Token is:", fcmToken);
} else {
this.showAlert("Failed", "No token received");
}
}
requestPermission = async () => {
try {
await firebase.messaging().requestPermission();
// User has authorised
} catch (error) {
// User has rejected permissions
}
}
messageListener = async () => {
this.notificationListener = firebase.notifications().onNotification((notification) => {
const { title, body } = notification;
this.showAlert(title, body);
});
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
});
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
}
this.messageListener = firebase.messaging().onMessage((message) => {
console.log(JSON.stringify(message));
});
}
showAlert = (title, message) => {
Alert.alert(
title,
message,
[
{text: "OK", onPress: () => console.log("OK Pressed")},
],
{cancelable: false},
);
}
}
I have no ideia what I'm missing. Maybe some function out of scope...But I can't figure out
I changed useEffect to componentDidMount() and It worked great
componentDidMount() {
this.checkPermission();
this.messageListener();
}

Resources