here is the Context : My iOS swift app
- records a sound,
- creates a firebase object,
- renames the file with the key of the object
- uploads on firebase cloud the wav file.
- A firebase cloud function is triggered that sends the audio file to google speech .recognize
My problem : When I upload manually a sound file to the cloud storage, it works fine, but when the file is uploaded by the app automatically, I get the following error message as a return form the speech API :
{ Error: The caller does not have permission at /user_code/node_modules/@google-cloud/speech/node_modules/grpc/src/node/src/client.js:554:15
code: 7, metadata: Metadata { _internal_repr: {} }, note: 'Exception occurred in retry method that was not classified as transient' }
Here is the swift part :
func uploadFile(fileName:String){
// File located on disk
let localFileURL = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask)[0]
let fileURL = localFileURL.appendingPathComponent(fileName)
if FileManager.default.fileExists(atPath: fileURL.path) {
print("FilePath", fileURL.path)
// Create a reference to the file you want to upload
let newMnemoRef = MnemoDatabase.shared.createNew()
let newMnemoId = newMnemoRef.key
let filename=newMnemoId+".wav"
//let filename=fileName
let audioStorageRef = storage.reference().child(filename)
let storagePath = "gs://\(audioStorageRef.bucket)/\(audioStorageRef.fullPath)"
print(storagePath)
// Upload the file to the path "audio"
let uploadTask = audioStorageRef.putFile(from: fileURL, metadata: nil) { metadata, error in
if let error = error {
print("Upload error : ", error.localizedDescription)
} else {
// Metadata contains file metadata such as size, content-type, and download URL.
print ("OK")
}
}
// Add a progress observer to an upload task
let observer = uploadTask.observe(.success) { snapshot in
print("uploaded!")
newMnemoRef.child("audio").setValue([
"encoding_converted":"LINEAR16",
"sampleRate_converted":"44100",
"path_converted":storagePath])
}
} else {
print ("Non existent file", fileURL.path)
}
}
The cloud function calling the the speech API is fine with manually uploaded files. here is the extract
const request = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: language,
speechContexts: context
};
speech.recognize(uri, request)
The cloud storage bucket and cloud function all share the same project credentials. I removed all authentification from the bucket
// Anyone can read or write to the bucket, even non-users of your app.
// Because it is shared with Google App Engine, this will also make
// files uploaded via GAE public.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
I even tried hard coding the path into the cloud function, but to no avail.
I will appreciate any help