Firebase storage download audio files in React Native - firebase

I'm using firebase/storage to set up audio file downloading/uploading. I have the audio file in my firestore storage already.
With the following code, I am able to get the download URL of the specific file:
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/storage';
static async downloadMedia(mediaRef: string) {
try {
var storage = firebase.storage();
var pathReference = storage.ref(mediaRef);
const downloadUrl = await pathReference.getDownloadURL();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
var blob = xhr.response;
};
xhr.open('GET', downloadUrl);
return downloadUrl;
} catch (e) {
switch (e.code) {
case 'storage/object-not-found':
console.warn('File does not exist.');
break;
case 'storage/unauthorized':
console.warn('Unauthorized.');
break;
case 'storage/canceled':
console.warn('Upload cancelled.');
break;
case 'storage/unknown':
console.warn('Unknown error.');
break;
}
}
}
However, I do not understand how to use the firebase library to download the file itself with the URL that it provides me.
Thanks.

Found a solution which doesn't involve me downloading the media but instead playing it directly with the download URL.
Using package 'expo-av'.
Hope this helps someone in my shoes!
export default function AudioPlay({ mediaDownloadUrl } : AudioPlayProps) {
const [sound, setSound] = React.useState<Audio.Sound | null>(null);
async function playSound() {
if (typeof mediaDownloadUrl !== 'string') return null;
try {
const { sound } = await Audio.Sound.createAsync(
{ uri: mediaDownloadUrl }
);
setSound(sound);
await sound.playAsync();
} catch (e) {
console.warn(e);
}
}
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync(); }
: undefined;
}, [sound]);
// ....

Related

How to get stripe customers in next js

I am using Stripe in my NextJs project and have tried to get customers list in my app but have not succeeded. If anyone knows how to get it, please instruct me on how to do that.
This is my code:
import { loadStripe } from "#stripe/stripe-js";
async function getStripeCustomers(){
const stripe = await loadStripe(
process.env.key
);
if (stripe) {
// there was a toturail for node.js like this.
console.log(stripe.customers.list())
}
}
useEffect(() => {
getStripeCustomers()
}, []);
I think you should do this logic in backend so create a route in api folder then try this code.
// api/payment/get-all-customers.js
import Stripe from "stripe";
export default async function handler(req, res) {
if (req.method === "POST") {
const { token } = JSON.parse(req.body);
if (!token) {
return res.status(403).json({ msg: "Forbidden" });
}
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET, {
apiVersion: "2020-08-27",
});
try {
const customers = await stripe.customers.list(); // returns all customers sorted by createdDate
res.status(200).json(customers);
} catch (err) {
console.log(err);
res.status(500).json({ error: true });
}
}
}
Now from frontend send a POST request to newly created route.

MSW(Mock Service Worker) in Next js first render not working

I use msw with Next js. But at First render, cannot connect api
this is index.tsx
import { useQuery } from "#tanstack/react-query";
import axios from "axios";
const Home = () => {
const getFruit = async () => {
const { data } = await axios.get("/api");
return data;
};
const { data } = useQuery(["dfa"], getFruit);
console.log("data: ", data);
return <div>Hello world</div>;
};
export default Home;
And i capture log in dev tool
In terminal compiling /_error (client and server).. error is showing.
I write code in mocks/index.ts like
async function initMocks() {
if (typeof window === "undefined") {
const { server } = await import("./server");
server.listen();
} else {
const { worker } = await import("./browser");
worker.start();
}
}
initMocks();
export {};
Also I check this code is running before index.tsx.
I think msw work late then first rendering. Is it right? How can I solve this problem?

expo react native upload image to firebase storage

I am trying to upload an image from the phone library with expo-image-picker to Firebase storage and download the URL to save it in Firestore but for some reason, my app keeps crashing on (iPhone) without any error. I have tried every possible way to fix this issue(running my code line by line etc) but nothing has yet fixed this issue.
Has anyone encountered a similar issue and could help me with this particular problem? I have been stuck for a few days now. It would be a big help. Thank you in advance.
Here is my code:
Turning image to blob. at First, I used the fetch method but this seems to work better.
const urlToBlob = async (url) => {
return await new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open("GET", url);
xhr.responseType = "blob"; // convert type
xhr.send();
});
};
Uploading an image to storage. Sometimes it uploads but if you upload again it crashes.
const uploadImageAsync = async (imageUri) => {
let blob;
const imageRef = imageUri.substring(imageUri.lastIndexOf("/"));
try {
blob = await urlToBlob(imageUri);
const ref = await firebase.storage().ref().child(imageRef);
await ref.put(blob);
return await ref.getDownloadURL();
} catch (error) {
console.log(
"🚀 ~ file: eventServices.jsx ~ line 33 ~ createEvent ~ error",
error
);
} finally {
blob.close();
console.log("blob closed");
}
};
Here I get the image and pass it to my function which should return the URL to the image. URL then should get saved in Firestore.
export const createEvent = async (eventObj) => {
const imageUri = eventObj.image;
try {
const downloadUrl = uploadImageAsync(imageUri);
console.log(downloadUrl );
await firebase
.firestore()
.collection("events")
.add({ ...eventObj, image: downloadUrl });
console.log("Event added!");
} catch (error) {
console.log(
"🚀 ~ file: eventServices.jsx ~ line 62 ~ createEvent ~ error",
error
);
}
};

Stream and Future in Dart

I've been using basic async/await for some time without many problems and I thought I understood how it worked. Can't say I'm an expert in it, but I understadn the gist of it. I just can't get my head around Streams though. Before today I thought I understood how they worked (basically ala Reactive Programming), but I can't get them to work in Dart.
I'm working on a persistance layer with the possibility of saving and retrieving (json) files. I've been using the fileManager example as a guideline.
import 'dart:io';
import 'dart:async';
import 'package:intl/intl.dart'; //date
import 'package:markdowneditor/model/note.dart';//Model
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:flutter/foundation.dart'; //log
import 'package:simple_permissions/simple_permissions.dart';//OS permissions
class FileManager {
static final FileManager _singleton = new FileManager._internal();
factory FileManager() {
return _singleton;
}
FileManager._internal();
Future<String> get _localPath async {
final directory = (await getApplicationDocumentsDirectory()).toString();
return p.join(directory, "notes"); //path takes strings and not Path objects
}
Future<File> writeNote(Note note) async {
var file = await _localPath;
file = p.join(
file,
DateFormat('kk:mm:ssEEEMMd').format(DateTime.now()) +
" " +
note.title); //add timestamp to title
// Write the file
SimplePermissions.requestPermission(Permission.WriteExternalStorage)
.then((value) {
if (value == PermissionStatus.authorized) {
return File(file).writeAsString('$note');
} else {
SimplePermissions.openSettings();
return null;
}
});
}
Future<List<Note>> getNotes() async {
//need file access permission on android. use https://pub.dartlang.org/packages/simple_permissions#-example-tab-
final file = await _localPath;
SimplePermissions.requestPermission(Permission.ReadExternalStorage)
.then((value) {
if (value == PermissionStatus.authorized) {
try {
Stream<FileSystemEntity> fileList =
Directory(file).list(recursive: false, followLinks: false);
// await for(FileSystemEntity s in fileList) { print(s); }
List<Note> array = [];
fileList.forEach((x) {
if (x is File) {
var res1 = ((x as File).readAsString()).then((value2) {
Note note = Note.fromJsonResponse(value2);
return note;
}).catchError((error) {
debugPrint('is not file content futurestring getNoteError: $x');
return null;
});
var array2 = res1.then((value3) {
array.add(value3);
return array;
});
//?
} else {
debugPrint('is not file getNoteError: $x');
}
});
// Add the file to the files array
//Return the Future<List<Note>>
return array;
} catch (e) {
debugPrint('getNoteError: $e');
// If encountering an error, return 0
return null;
}
} else {
SimplePermissions.openSettings();
return null;
}
});
}
}
Obviously as it is it won't work, but even trying to await the loop using the commented out parts raises an error.
In "getNotes", after checking the permissions I want to get an array of all the files in the directory, parse them as Note objects and return the resulting array.
I get the list of files:
Stream<FileSystemEntity> fileList =
Directory(file).list(recursive: false, followLinks: false);
And for each one of them in the stream I want to parse the file into an object and append it to an array to return at the end.
List<Note> array = [];
fileList.forEach((x) {
if (x is File) {
var res1 = ((x as File).readAsString()).then((value2) {
Note note = Note.fromJsonResponse(value2);
return note;
}).catchError((error) {
debugPrint('is not file content futurestring getNoteError: $x');
return null;
});
var array2 = res1.then((value3) {
array.add(value3);
return array;
});
//?
} else {
debugPrint('is not file getNoteError: $x');
}
});
// Add the file to the files array
//Return the Future<List<Note>>
return array;
Stream.forEach() returns a Future. Your last return statement runs immediately after the for-each call, but should await it.
await fileList.forEach((x) {
...
https://api.dartlang.org/stable/2.2.0/dart-async/Stream/forEach.html

Uploading a form posted image buffer to Cloud Storage with Firebase Functions

Here's my cloud function. It's supposed to get an http posted image and upload it to storage, returning the url.
exports.uploadImageToEditor = functions.https.onRequest((req, res) => {
const img = JSON.parse(JSON.stringify(req.body));
const bucket = admin.storage().bucket();
return bucket.file('blog/foo.jpg').save(img.data, {
resumable: false,
metadata: {
contentType: 'image/jpeg'
}
})
.then(() => {
return cors(req, res, () => {
res.status(200).send({ "url": bucket.file('foo.jpg').getSignedUrl()});
});
});
});
This is how the image is actually sent in the client:
uploadImage(file, endPoint) {
if (!endPoint) {
throw new Error('Image Endpoint isn`t provided or invalid');
}
const formData = new FormData();
if (file) {
formData.append('file', file);
const req = new HttpRequest('POST', endPoint, formData, {
reportProgress: true
});
return this._http.request(req);
}
else {
throw new Error('Invalid Image');
}
}
I think you're probably looking for the save() method on File in the Admin SDK.
const bucket = admin.storage().bucket()
.file('my-file.jpg').save(blob)
.then(() => { /* ... */ });
You can also get back information about the file this way.
export const uploadImage = async (destination: string, image: Buffer) => {
const file = storage.bucket().file(destination);
await file.save(image, { contentType: yourContentType });
return file.publicUrl();
};
If you get a permission error, go to Firebase storage Rules and add this rule to allow to write in the directory :
service firebase.storage {
match /b/{bucket}/o {
match /blog/{anyPath=**} {
allow read;
allow write;
}
}
}

Resources