How to get downloadUrl after uploadString in firebase v9? - firebase

There is no documentation on firebase docs as to how to get UploadTask after uploadString is done in firebase v9.
const message4 = 'data:text/plain;base64,5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
uploadString(storageRef, message4, 'data_url').then((snapshot) => {
console.log('Uploaded a data_url string!');
});
or how can I get the downloadUrl after the uploadString is completed?

I got the answer.
uploadString(storageRef, uri, 'data_url').then((snapshot) => {
getDownloadURL(snapshot.ref).then(async (url) => {
// Url
})
})

Related

Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array. (Firebase cloud functions)

I am making a chat application where I am trying to send push notifications to when one user sends a message to the other user.
I am using firebase cloud functions with JavaScript and in the firebase functions log I can see that it's able to get the user who sends the message and the user who receives the message. But for some reason It's showing me that the token is empty.
Even though I have a token and I am able to print it in the log(The screenshot of firebase cloud functions log where you can see that token is being printed and I have partially marked over it).
For more reference I am also attaching the screenshot of my two collections in firebase -
All the users collection where the push token is being saved.(The structure is users>uid>{user_info}).
The chat collection screenshot where you can see the structure of chats.(The structure here is chatroom>chatid>chats>{chat_documents}).
My index.js file in functions folder for firebase is below-
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
exports.sendNotification = functions.firestore
.document('chatroom/{chatId}/chats/{message}')
.onCreate((snap) => {
console.log('----------------start function--------------------')
const doc = snap.data()
console.log(doc)
const idFrom = doc.idFrom
const idTo = doc.idTo
const contentMessage = doc.mesaage
console.log(`Starting to push token`)
// Get push token user to (receive)
admin
.firestore()
.collection('users')
.where('uid', '==', idTo)
.get()
.then(querySnapshot => {
querySnapshot.forEach(userTo => {
console.log(`Found user to: ${userTo.data().name}`)
console.log(`Found user to: ${userTo.data().pushtoken}`)
try {
// Get info of the user who is sending the message
admin
.firestore()
.collection('users')
.where('uid', '==', idFrom)
.get()
.then(querySnapshot2 => {
querySnapshot2.forEach(userFrom => {
console.log(`Found user from: ${userFrom.data().name}`)
const payload = {
notification: {
title: `"${userFrom.data().name}"`,
body: contentMessage,
badge: '1',
sound: 'default'
}
}
// Lets push to the target device
admin
.messaging()
.sendToDevice(payload,userTo.data().pushtoken)
.then(response => {
console.log('Successfully sent message:', response)
})
.catch(error => {
console.log('Error sending message:', error)
})
})
})
} catch(e){
console.log('Can not find pushToken target user')
}
})
})
return null
})
What might be the problem here as I am not able to figure it out? Your help would be really appreciated. Also kindly let me know if you want any more information regarding the same.

“user Does not exists” Firebase

I started this tutorial (https://www.freecodecamp.org/news/react-native-firebase-tutorial/) on Firebase and React Native. Everything is working well overall.
But I have this error: “User does not exist anymore.” for the Login.
However, users are well rooted in Firebase.
const onLoginPress = () => {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((response) => {
const uid = response.user.uid
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.get()
.then(firestoreDocument => {
if (!firestoreDocument.exists) {
alert("User does not exist anymore.")
return;
}
const user = firestoreDocument.data()
navigation.navigate('Home', {user})
})
.catch(error => {
alert(error)
});
})
.catch(error => {
alert(error)
})
}
With
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.get()
.then(firestoreDocument => {
if (!firestoreDocument.exists) {
alert("User does not exist anymore.")
return;
}
const user = firestoreDocument.data()
navigation.navigate('Home', {user})
})
you actually query the user document with the id corresponding to the user's uid in the users collection.
This document is normally created by the onRegisterPress() function in the tutorial. If you get the "User does not exist anymore." message, it means that the user document is not present in the collection.
So you need to check why this is the case: the onRegisterPress() function was not called? The doc was deleted? There are security rules that prevent creating the document? etc...

Retrieving/Handling Image URL From Firestore - React Native

I am new to React Native and Firebase (Firestore) and I'm developing an app where I have to retrieve posts to my feed.
I can retrieve all data I need, but I don't know how to display the image in the frontend. The post document has a field image which is saved as an URL and stored in the Firebase storage.
Does anyone know how can I get the image displayed? I am using a to sort the data.
This is my retrieveData() and it prints the correct URL:
retrieveData() {
var that = this;
let postRef = firebase
.firestore()
.collection("posts")
.orderBy("timestamp", "desc")
.limit(10);
let allPosts = postRef
.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
var post = that.state.posts;
const data = (doc.id, "=>", doc.data());
that.setState({ posts: post });
console.log(data.image);
post.push({
id: data.id,
title: data.title,
description: data.description,
expireDate: data.expireDate,
timestamp: data.timestamp,
image: data.image,
});
});
})
.catch((err) => {
console.log("Error getting documents", err);
});
}
And this is how I am calling the image in the flatlist:
<Image
source={post.image}
style={styles.postImage}
/>
Can anyone help me with that?
Thanks in advance.
Can you share the image url ? And preferred way is to store image on the firebase storage and get the downloadUrl then store that url in the firestore document.
fileref.put(file)
.then(snapshot => {
return snapshot.ref.getDownloadURL(); // Will return a promise with the download
link
})
.then(downloadURL => {
console.log(`Successfully uploaded file and got download link - ${downloadURL}`);
return downloadURL;
})
.catch(error => {
// Use to signal error if something goes wrong.
console.log(`Failed to upload file and get link - ${error}`);
});

Firebase functions/firestore not working and catch returning an empty object

I would just like to access my Firestore Database from within my Firebase Functions. I have tried to follow all the documentation and other stack overflow questions but still it is not working. Here is my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.test = functions.https.onRequest((request, response) => {
admin
.firestore()
.collection('users')
.get()
.then(querySnapshot => {
const arrUsers = querySnapshot.map(element => element.data());
return response.send(arrUsers);
}).catch((error) => {
// It is coming in here, and this below just returns '{}'
response.send(error);
});
});
What am I doing wrong?
The get() method of a CollectionReference returns a QuerySnapshot which "contains zero or more DocumentSnapshot objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach() method".
Therefore you should do as follows, calling map() on querySnapshot.docs:
exports.test = functions.https.onRequest((request, response) => {
admin
.firestore()
.collection('users')
.get()
.then(querySnapshot => {
const arrUsers = querySnapshot.docs.map(element => element.data());
//return response.send(arrUsers); //You don't need to use return for an HTTPS Cloud Function
response.send(arrUsers); //Just use response.send()
}).catch(error => {
//response.send(error);
response.status(500).send(error) //use status(500) here
});
});
Note the changes to the code for returning the response and handling the error. I would suggest that you watch this official Firebase video on HTTPS Cloud Functions: https://www.youtube.com/watch?v=7IkUgCLr5oA, it's a must!

Firestore - Get document collections

I would automate the backup process of a firestore database.
The idea is to loop over the root document to build a JSON tree, but I didn't find a way to get all collections available for a document. I guess it's possible as in firestore console we can see the tree.
Any ideas?
ref doc: https://firebase.google.com/docs/reference/js/firebase.firestore
Its possible on web (client side js)
db.collection('FirstCollection/' + id + '/DocSubCollectionName').get().then((subCollectionSnapshot) => {
subCollectionSnapshot.forEach((subDoc) => {
console.log(subDoc.data());
});
});
Thanks to #marcogramy comment
firebase.initializeApp(config);
const db = firebase.firestore();
db.settings({timestampsInSnapshots: true});
const collection = db.collection('user_dat');
collection.get().then(snapshot => {
snapshot.forEach(doc => {
console.log( doc.data().name );
console.log( doc.data().mail );
});
});
Update
API has been updated, now function is .listCollections()
https://googleapis.dev/nodejs/firestore/latest/DocumentReference.html#listCollections
getCollections() method is available for NodeJS.
Sample code:
db.collection("Collection").doc("Document").getCollections().then((querySnapshot) => {
querySnapshot.forEach((collection) => {
console.log("collection: " + collection.id);
});
});
If you are using the Node.js server SDK you can use the getCollections() method on DocumentReference:
https://cloud.google.com/nodejs/docs/reference/firestore/0.8.x/DocumentReference#getCollections
This method will return a promise for an array of CollectionReference objects which you can use to access the documents within the collections.
As mentioned by others, on the server side you can use getCollections(). To get all the root-level collections, use it on the db like so:
const serviceAccount = require('service-accout.json');
const databaseURL = 'https://your-firebase-url-here';
const admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
const db = admin.firestore();
db.settings({ timestampsInSnapshots: true });
db.getCollections().then((snap) => {
snap.forEach((collection) => {
console.log(`paths for colletions: ${collection._referencePath.segments}`);
});
});

Resources