In my cloud functions, I'm trying to delete an image based on its url, but I think that I don't use correctly the API as I'm getting errors :
const admin = require('firebase-admin');
exports.deleteImageWhenOfferDeleted = functions.firestore
.document('offers/{offerId}')
.onDelete(async(snap, context) => {
console.log('----------------start function--------------------')
const deletedOffer = snap.data();
var imageUrlToDelete = deletedOffer.imageUrl;
await admin.storage.getPathStorageFromUrl(imageUrlToDelete).delete();
function getPathStorageFromUrl(url){
const baseUrl = "https://firebasestorage.googleapis.com/v0/b/muslim-coloc.appspot.com/o/";
let imagePath = url.replace(baseUrl,"");
const indexOfEndPath = imagePath.indexOf("?");
imagePath = imagePath.substring(0,indexOfEndPath);
imagePath = imagePath.replace("%2F","/");
return imagePath;
}
I think you're missing brackets after storage word.
You need to get an instance of storage object.
admin.storage.getReferenceFromUrl(...)
should be
admin.storage().getReferenceFromUrl(...)
BTW: Consider using TypeScript, because it catches errors like that during compilation.
Related
I want to automate my staking on The Sandbox. For that I need in the first step to interact with the mSand-Matic Pool Contract. It is this one: https://polygonscan.com/address/0x4ab071c42c28c4858c4bac171f06b13586b20f30#code
I have written a little program in a GitHub repository to show what I have done: https://github.com/ChristianErdtmann/mSandMaticStakingAutomation
Or here is the code example from the contract-interact.js
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
mSandMaticContract.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780')
The ABI I have taken from the contract link on the top. But it seems there is a problem.
I tried for testing to read something from the contract. For that I used the function balanceOf(address), how you can see in the code.
But I always get this error:
TypeError: mSandMaticContract.balanceOf is not a function
I found the solution
web3 needs .methots to get acces to the balanceOf() function
if we want only to read so we need to add .call()
we need to add await before the function is called this needs to be in a asynchonus function
So the final working code is:
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
asyncCall()
async function asyncCall() {
console.log(await mSandMaticContract.methods.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780').call())
}
If you dont want only to read you need addtional to sign the transaction with:
The solution is, to sign the transaction before sending we can doing this with any method by this code:
encoded = mSandMaticContract.methods.getReward().encodeABI()
var block = await web3.eth.getBlock("latest");
var gasLimit = Math.round(block.gasLimit / block.transactions.length);
var tx = {
gas: gasLimit,
to: publicKey,
data: encoded
}
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction).on('receipt', console.log)
})
I'm using the azure file storage, and using express JS to write a backend to render the contents stored in the azure file storage.
I am writing the code based on https://learn.microsoft.com/en-us/javascript/api/#azure/storage-file-share/shareserviceclient?view=azure-node-latest
const { ShareServiceClient, StorageSharedKeyCredential } = require("#azure/storage-file-share");
const account = "<account>";
const accountKey = "<accountkey>";
const credential = new StorageSharedKeyCredential(account, accountKey);
const serviceClient = new ShareServiceClient(
`https://${account}.file.core.windows.net`,
credential
);
const shareName = "<share name>";
const fileName = "<file name>";
// [Node.js only] A helper method used to read a Node.js readable stream into a Buffer
async function streamToBuffer(readableStream) {
return new Promise((resolve, reject) => {
const chunks = [];
readableStream.on("data", (data) => {
chunks.push(data instanceof Buffer ? data : Buffer.from(data));
});
readableStream.on("end", () => {
resolve(Buffer.concat(chunks));
});
readableStream.on("error", reject);
});
}
And you can view the contents through
const downloadFileResponse = await fileClient.download();
const output = await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()
Thing is, I only want to find if the file exists and not spend time downloading the entire file, how could I do this?
I looked at https://learn.microsoft.com/en-us/javascript/api/#azure/storage-file-share/shareserviceclient?view=azure-node-latest
to see if the file client class has what I want, but it doesn't seem to have methods useful for this.
If you are using #azure/storage-file-share (version 12.x) Node package, there's an exists method in ShareFileClient. You can use that to find if a file exists or not. Something like:
const fileExists = await fileClient.exists();//returns true or false.
I would like to ask if is it possible to add data in a nested array.The result i want is this
But i get this when i add a new rating with the code i use
async function getAll(){
const userEmail= firebase.firestore().collection('users')
const snapshot=await userEmail.where('email','==',index.email).get()
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
snapshot.forEach(doc => {
userEmail.doc(doc.id).set({userRatings2:firebase.firestore.FieldValue.arrayUnion({parking:[markerName]})},{merge:true})
userEmail.doc(doc.id).set({userRatings2:firebase.firestore.FieldValue.arrayUnion({rating:[currentRating]})},{merge:true})
console.log(userEmail.doc(doc.id));
});
}
getAll()
Unfortunately in Firebase Firestore you can't even change a simple Array value at a specific index. That means also that you can't save nested array values. You can read more about it on this answer.
The only way to do it is to download the whole Array make your modifications and save the whole array again to the databse. There is not much context of your app so I can't tell if that is a good solution for you. It depends how much data you have in the array.
I've managed to do it by using forEach function to an array of image path
const [imageUri, setImageUri] = useState([]);
const [uploading, setUploading] = useState(false);
const UploadImage = () => {
setUploading(true);
imageUri.forEach(async (image, index) => {
// setTransferred(0);
const pathToFile = image;
let filename = pathToFile.substring(pathToFile.lastIndexOf('-') + 1);
const extension = filename.split('.').pop();
const name = filename.split('.').slice(0, -1).join('.');
filename = name + Date.now() + '.' + extension;
const reference = storage().ref().child(`/userprofile/${filename}`);
// path to existing file on filesystem
// uploads file
const task = reference.putFile(pathToFile);
try {
await task;
const url = await reference.getDownloadURL();
downloadableURI.push(url);
if (index == imageUri.length - 1) {
setUploading(false);
Alert.alert(
'Image uploaded!',
'Your image has been uploaded to the Firebase Cloud Storage Successfully!',
);
}
} catch (e) {
console.log(e);
}
});
};
whenever the function is called, then the array of images is uploaded to firebase storage,
I'm trying to add new fields to a new document after calculation, that I have to do when a new doc is created. But, the field isn't added.
I have deploy this code without any errors but when a new doc is added in this path, nothing happens..
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.test = functions.firestore.document('a/{a.id}/b/{b.id}/c/d')
.onCreate(async(snapshot, context) => {
const data = snapshot.data();
const userRef = db.doc(`a/${a.id}/b/${b.id}/c/d`);
var result = 1+2; //just for lighter code example
return userRef.update({
result: result
});
})
Your wildcards are invalid. You can't have a dot in the wildcard name. I'm kind of surprised that the Firebase CLI allowed you to deploy this function. Also, you're not using the wildcards correctly, even if those wildcards were valid.
There is an easier way to get a reference to the document that was just created. You can use snapshot.ref.
exports.test = functions.firestore.document('a/{a}/b/{b}/c/d')
.onCreate(async(snapshot, context) => {
var result = 1+2; //just for lighter code example
return snapshot.ref.update({
result: result
});
})
If you do want to use the wildcard values, you should use context.params instead, as described in the documentation.
I made Firestore Could Function Where I have Database Like this
'posts/{postId}/comments/{commentId}'
and Function I made To Increase Field In PostId when New Comment Added
the Funtion has Deploy But it`s Never Execute when adding New Comment
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.comment= functions.firestore
.document('posts/{postId}/comments/{commentId}')
.onWrite((change, context) => {
const commentId = event.params.commentId;
const postId = event.params.postId;
const docRef = admin.firestore().collection('posts').doc(postId);
return docRef.update({numberOfComments:200});
});
I Added Many Comment Even Executions is 0
change this:
const commentId = event.params.commentId;
const postId = event.params.postId;
into this:
const commentId = context.params.commentId;
const postId = context.params.postId;
more info here:
https://firebase.google.com/docs/functions/beta-v1-diff
Before Firebase SDK (<= v0.9.1) version event.params.id was worked. but Now (v1.0.0) android provide documentation to use context.params.id.
Use context insted of event, your problem will be solve.
const commentId = event.params.commentId;
const postId = event.params.postId;
Thanks.