Why my download button is not doing anything? Firebase, react - reactjs

I'm following the firebase documentation for web to download the files related to a document in firestore. I practically pasted the code to achieve this, but when I click the element is not showing anything on console.
import { ref, getDownloadURL } from 'firebase/storage'
export const downloadMethod = (path) => {
getDownloadURL(ref(storage, path))
.then(url => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
const blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
})
.catch(error => {
throw error
})
}
Before this I was having cors error but I solved it using
[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
I want the website to download the requested file when I hit the button.

I guess you are missing the reference to the storage
import { getStorage, ref, getDownloadURL } from "firebase/storage";
const storage = getStorage();
...

Since the example in the documentation doesn't work, I looked for other methods in the documentation itself, and I managed to do exactly what I wanted by using getBlob()
This is my final function:
import { ref, getBlob } from 'firebase/storage'
import { storage } from '../firebase/firebase.config'
getBlob(ref(storage, 'files/MyFile.pdf'))
.then((blob) => {
const href = URL.createObjectURL(blob)
const a = Object.assign(document.createElement('a'), {
href,
style: 'display:none',
download: 'myFile.pdf' // This is where you set the name of the file you're about to download
})
a.click()
URL.revokeObjectURL(href)
a.remove()
}).catch((error)=>{
console.error(error)
})
If you feel there's something I can change, you can feel free to tell me

Related

I have CORS error even if I enable it on nest server

Hey I think the problem in my code is on the frontend react cod because if I use Postmap my api on nest works correct.
What I have to do: I'm checking on the backend if the input phare is correct. If yes it will answers to the post request sending an object contained urls of images than I will render.
In my console log when I try to post the request I have the attached image error:
This is my function that handle the request:
const getImages = async (secret) => {
try {
const response = await axios.post('http://localhost:5000/secret', {secret});
return response.data;
} catch (error) {
console.log(error);
}
}
const handleSecret = async (e) => {
secret = phrase;
console.log(secret)
if (e.key === "Enter" || e.type === "click") {
const images = await getImages(secret);
if (images) {
//render image if true
setSecret(true);
} else {
window.alert("Incorrect phrase");
setSecret(false);
}
}
}
I need community help!
I have already enable cors on nest backend:
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(5000);
app.enableCors();
}
bootstrap();
You need to enable cors before using app.listen(). Think of regular express middleware, anything after app.listen() doesn't get bound to the server, it's the same thing here

Google OAuth components must be used within GoogleOAuthProvider

I want to build my next js project in which i am using
https://www.npmjs.com/package/#react-oauth/google
but when I build it i get the following :
this is layout.js and in _app.js I have all the components wrapped in GoogleOAuthProvider
import { GoogleLogin } from '#react-oauth/google';
import {FcGoogle} from "react-icons/Fc"
import { useGoogleLogin } from '#react-oauth/google';
export default function Layout({ children }) {
const client_id = ""
const responseGoogle = (response) => {
console.log(response);
}
CUTTED (NOT RELEVANT)
const login = useGoogleLogin({
onSuccess: codeResponse => {
const { code } = codeResponse;
console.log(codeResponse)
axios.post("http://localhost:8080/api/create-tokens", { code }).then(response => {
const { res, tokens } = response.data;
const refresh_token = tokens["refresh_token"];
const db = getFirestore(app)
updateDoc(doc(db, 'links', handle), {
refresh_token : refresh_token
})
updateDoc(doc(db, 'users', useruid), {
refresh_token : refresh_token
}).then(
CUTTED (NOT RELEVANT)
)
}).catch(err => {
console.log(err.message);
})
},
onError: errorResponse => console.log(errorResponse),
flow: "auth-code",
scope: "https://www.googleapis.com/auth/calendar"
});
return (
<>
CUTTED (NOT RELEVANT)
</>
)
}
Everything works perfect in dev mode but it does not want to build
I've faced this issue too. So I use 'GoogleLogin' instead of 'useGoogleLogin', then you can custom POST method on 'onSuccess' property.
import { GoogleLogin, GoogleOAuthenProvider} from '#react-oauth/google';
return(
<GoogleOAuthProvider clientId="YOUR CLIENT ID">
<GoogleLogin
onSuccess={handleLogin}
/>
</GoogleOAuthProvider>
The async function will be like...
const handleLogin = async = (credentialResponse) => {
var obj = jwt_decode(credentialResponse.credential);
var data = JSON.stringify(obj);
console.log(data);
const data = {your data to send to server};
const config = {
method: 'POST',
url: 'your backend server or endpoint',
headers: {},
data: data
}
await axios(config)
}
Spending whole day, this solve me out. Just want to share.
You have to wrap your application within GoogleOAuthProvider component. Please keep in mind that you will need your client ID for this.
import { GoogleOAuthProvider } from '#react-oauth/google';
<GoogleOAuthProvider clientId="<your_client_id>">
<SomeComponent />
...
<GoogleLoginButton onClick={handleGoogleLogin}/>
</GoogleOAuthProvider>;

Why does my API return "You are not subscribed to this APi" even with the X-RapidAPI-Key?

The link to my rapidAPI is below
https://rapidapi.com/ytdlfree/api/youtube-v31?utm_source=youtube.com%2FJavaScriptMastery
This is my RAPID API code:
import axios from "axios";
const BASE_URL = 'https://youtube-v31.p.rapidapi.com';
const options = {
params: {
maxResults: '50'
},
headers: {
'X-RapidAPI-Key': process.env.REACT_APP_RAPID_API_KEY,
'X-RapidAPI-Host': 'youtube-v31.p.rapidapi.com'
}
};
export const fetchFromAPI = async(url) =>{
const { data } = await axios.get(`${BASE_URL}/${url}`, options);
return data;
}
This is for fetching the data:
import { fetchFromAPI } from '../utils/fetchFromAPI';
const Feed = () => {
const [selectedCategory, setSelectedCategory] = useState('New');
const [videos, setVideos] = useState([]);
useEffect (() =>{
fetchFromAPI(`search?part=snippet&q=${selectedCategory}`)
.then((data) => setVideos(data.items))
.catch(error => {
if (error.response) {
// Request made but the server responded with an error
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// Request made but no response is received from the server.
console.log(error.request);
} else {
// Error occured while setting up the request
console.log('Error', error.message);
}
});
I saved my API key to the .env file at the root directory of this application but it kept showing message:
You are not subscribed to this API
[[Prototype]]
Object
How can I solve this?
First you need to subscribe API key..
Second , use env variable like this ..
**REACT_APP_RAPID_API_KEY = '9fbc4844e8msfdf8absdzgd3ffp182459jsdfdsf909d079cdds'**
don't put semicolon or anything at the end of env variable like this ..
REACT_APP_RAPID_API_KEY = '9fbc4844e8msfdf8absdzgd3ffp182459jsdfdsf909d079cdds';
Also , try to log the env variable in the console like ..
console.log(process.env.REACT_APP_RAPID_API_KEY);
try to restart the server after changing env file ...
yarn start / npm start

POST https://ipfs.infura.io:5001/ipfs/api/v0/add?stream-channels=true&progress=false 403 (Forbidden). HTTPError: ipfs method not supported

Below is how i create the client.
import { create as ipfsHttpClient } from 'ipfs-http-client';
const projectId = 'xx';
const projectSecret = 'xx';
const auth = `Basic ${Buffer.from(`${projectId}:${projectSecret}`).toString('base64')}`;
const options = {
host: 'ipfs.infura.io',
protocol: 'https',
port: 5001,
apiPath: '/ipfs/api/v0',
headers: {
authorization: auth,
},
};
const dedicatedEndPoint = 'https://xx.infura-ipfs.io';
const client = ipfsHttpClient(options);
Here is the function that will be called from front-end that takes in a file, uploads to IPFS and returns URL. Please note that the "ipfsHTTPClient()" is just the create function.
const uploadToIPFS = async (file) => {
try {
const added = await client.add({ content: file });
const url = `${dedicatedEndPoint}${added.path}`;
return url;
} catch (error) {
console.log('Error uploading file to IPFS: ', error);
}
};
The error I am getting is
POST https://ipfs.infura.io:5001/ipfs/api/v0/add?stream-channels=true&progress=false 403 (Forbidden)
When i console log the error it says the IPFS method is not supported.
On the IPFS forum, i have seen someone say that add function does not work anymore but i have also seen people using it and it working. Im not sure whats wrong here.
Here is how i call the function on front-end
const { uploadToIPFS } = useContext(NFTContext);
// function called from useDropzone
const onDrop = useCallback(async (acceptedFile) => {
const url = await uploadToIPFS(acceptedFile[0]);
setFileUrl(url);
}, []);
All the above code is correct and the error was from Next.js
Needed to add
images: {
domains: ['xx.infura-ipfs.io'],
},
to the next.config.js file.
I have resolved this problem
so make sure first you have installed buffer
npm install --save buffer
then import it in your file
import {Buffer} from 'buffer';
then it works successfully
import { create } from "ipfs-http-client";
import { Buffer } from "buffer";
const projectId = "YOUR_INFURA_PROJECT_ID";
const projectSecret = "YOUR_INFURA_PROJECT_SECRET";
const auth = `Basic ${Buffer.from(`${projectId}:${projectSecret}`).toString(
"base64"
)}`;
const client = create({
host: "ipfs.infura.io",
port: 5001,
protocol: "https",
apiPath: "/api/v0",
headers: {
authorization: auth,
},
});
const uploadFiles = async (e) => {
e.preventDefault();
setUploading(true);
if (text !== "") {
try {
const added = await client.add(text);
setDescriptionUrl(added.path);
} catch (error) {
toast.warn("error to uploading text");
}
}

Downloading Files from Firebase Storage

I have a function that when clicked downloads a file from firebase storage. I have implemented the function as in the firebase documentation v8. I have also applied the cors policy to allow downloads but the problem is that file is still not being downloaded and I am not getting an error.
Kindly help on this.
Below is my download function.
const handleDownloadFile = async file => {
try {
const url = file.downloadURL;
console.log(file);
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = event => {
const blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
} catch (error) {
console.log(error.message);
}
};
The function accepts the details of the file. Below is a sample object that
{
name: 'Ndov network LOGO - 400.png',
downloadURL: 'https://firebasestorage.googleapis.com/v0/b/tkiā€¦=media&token=2680cc-4043-4676-992a-7e64fe8342f2',
uuid: '1b1c0a4b-80a5-42d4-a698-719a26e3f281'
}
kindly help me understand why I am not getting any errors and the still download, not working.
Easiest way to download file on url that comes from API is to
window.open(url,'_blank');
or you can use some library for downloading files in blob format like
https://www.npmjs.com/package/file-saver
This will open a window and ask the user where they want to save the file locally.
import { getStorage, ref, uploadBytes, getBlob } from 'firebase/storage'
export const downloadFile = (refToFile) => {
const storage = getStorage()
const fileRef = ref(storage, refToFile)
const blob = await getBlob(fileRef)
const blobUrl = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = blobUrl
link.download = 'myfilename.pdf'
link.click()
}

Resources