When I started to search this online people said that it's impossible to do it with Firebase Storage and there wasn't that many good tutorials explaining how to do it with other types of servers. That is why I'm so proud of solving this problem. Hopefully people who face the same problem find this because this at least worked for me June 2020.
const recordingSettings = {
android: {
extension: ".m4a",
outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4,
audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC,
sampleRate: 44100,
numberOfChannels: 2,
bitRate: 128000,
},
ios: {
extension: ".m4a",
outputFormat: Audio.RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEG4AAC,
audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_MIN,
sampleRate: 44100,
numberOfChannels: 2,
bitRate: 128000,
linearPCMBitDepth: 16,
linearPCMIsBigEndian: false,
linearPCMIsFloat: false,
},
};
const db = firebase.database();
const [isRecording, setIsRecording] = useState(false);
const [recording, setRecording] = useState(null);
const [sound, setSound] = useState(null);
const [isPlaying, setIsPlaying] = useState(false);
const startRecording = async () => {
// stop playback
if (sound !== null) {
await sound.unloadAsync();
sound.setOnPlaybackStatusUpdate(null);
setSound(null);
}
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
shouldDuckAndroid: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
playThroughEarpieceAndroid: false,
staysActiveInBackground: true,
});
const _recording = new Audio.Recording();
try {
await _recording.prepareToRecordAsync(recordingSettings);
setRecording(_recording);
await _recording.startAsync();
console.log("recording");
setIsRecording(true);
} catch (error) {
console.log("error while recording:", error);
}
};
const stopRecording = async () => {
try {
await recording.stopAndUnloadAsync();
} catch (error) {
// Do nothing -- we are already unloaded.
}
const info = await FileSystem.getInfoAsync(recording.getURI());
console.log(`FILE INFO: ${JSON.stringify(info)}`);
await Audio.setAudioModeAsync({
allowsRecordingIOS: false,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
playsInSilentLockedModeIOS: true,
shouldDuckAndroid: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
playThroughEarpieceAndroid: false,
staysActiveInBackground: true,
});
const { sound: _sound, status } = await recording.createNewLoadedSoundAsync(
{
isLooping: true,
isMuted: false,
volume: 1.0,
rate: 1.0,
shouldCorrectPitch: true,
}
);
setSound(_sound);
setIsRecording(false);
};
const uploadAudio = async () => {
const uri = recording.getURI();
try {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
try {
resolve(xhr.response);
} catch (error) {
console.log("error:", error);
}
};
xhr.onerror = (e) => {
console.log(e);
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", uri, true);
xhr.send(null);
});
if (blob != null) {
const uriParts = uri.split(".");
const fileType = uriParts[uriParts.length - 1];
firebase
.storage()
.ref()
.child(`nameOfTheFile.${fileType}`)
.put(blob, {
contentType: `audio/${fileType}`,
})
.then(() => {
console.log("Sent!");
})
.catch((e) => console.log("error:", e));
} else {
console.log("erroor with blob");
}
} catch (error) {
console.log("error:", error);
}
};
const downloadAudio = async () => {
const uri = await firebase
.storage()
.ref("nameOfTheFile.filetype")
.getDownloadURL();
console.log("uri:", uri);
// The rest of this plays the audio
const soundObject = new Audio.Sound();
try {
await soundObject.loadAsync({ uri });
await soundObject.playAsync();
} catch (error) {
console.log("error:", error);
}
};
Top comments (7)
For those who wants to Upload to firestore v9
here is the updated code.
*These are the Firebase Storage rules setup:
*
Above rules are to be applied through your Firebase Console.
Imports
Then just delete whatever is not highlighted from the imports. _(Sorry I could not clean the imports up for you, I am kind on a rush.) _
The backend exporting functions for firebase (Optional)
**Now the code to use ( expo-av ) is required !
**just google it easy to install the dependency.
*Finally upload to firebase Storage and Update Firestore !
*
Sorry for the mess, but I am a noob and I hope others can take me step by step like that.
Very helpful. I didn't know until now that the contentType and file extension were necessary for this to work. Image tags worked fine without them, but when I started uploading video, expo-av didn't know how to read the format.
I replied with a way to get the file to be applied to this code. Maybe this will help.
Your are amazing man ! I have been struggling with this for the last couple of days. I have no idea what I did not think of searching the main subject. I have been searching and digging into the details to fix one thing and break another. Thanks alot !
I will go ahead and read the code and apply it. I just got too excited and I had to thank you after reading the introduction !
You're such a boss ! Worked for me. Thank you so much
thank you brother, its work, i little change the code to web version 9, but it still work, thank you again lol :'D
I got an error as "bytes cannot be null" please help