The Problem
I'm using Google Drive to store application-specific data. I can read and write data to my drive buy whenever I want to update the config in the drive a new file is created instead of updating the old one.
I have tried the following:
Gave the file an ID but the following error appears
Unhandled Exception: DetailedApiRequestError(status: 400, message: The provided file ID is not usable.)
Got the ID generated by the API and used the same code and got the following error
Unhandled Exception: DetailedApiRequestError(status: 409, message: A file already exists with the provided ID.)
My Code:
final signIn.GoogleSignInAccount account = await _googleSignIn.signIn();
final authHeaders = await account.authHeaders;
final authenticateClient = GoogleAuthClient(authHeaders);
final driveApi = drive.DriveApi(authenticateClient);
File _data = await _report.backupData(); //gets data to be overwriten
final Stream<List<int>> mediaStream = _data.openRead();
var media = new drive.Media(mediaStream, _data.lengthSync());
var driveFile = new drive.File();
driveFile.parents=['appDataFolder'];
driveFile.name = "backup.mw";
final result = await driveApi.files.create(driveFile, uploadMedia: media,);
print("Upload result: ${result.id}");
The code you are using does a files.create file create will create a new file every time it is run.
final result = await driveApi.files.create(driveFile, uploadMedia: media,);
If you want to update an existing file then you will need to do Files.update
Related
I try to work with firebaseStorage in flutter Web but I have a problem when I send the image to storage, because that send me a message like "UnsupportedError (Unsupported operation: Platform._operatingSystem)" and I dont know how to fix, also, I configure all firebase in my proyect but I dont know If i have to add firebase hosting and more, I would like to know how to fix
this is my code
String imagePath = '';
if (image.path != '')
imagePath = await setImage(image: image, random_id: randomId);
Future<String> setImage({
required File image,
required String random_id,
}) async {
final Reference reference = _storage.ref().child("imageSave");
TaskSnapshot updateImage = await reference.child(random_id).putFile(image);
String link = await updateImage.ref.getDownloadURL();
return link;
}
I added flutterFire or firebase cli to my project but nothing happens I keep with error "UnsupportedError (Unsupported operation: Platform._operatingSystem)"
Iam uploading files to firebase storage and the referenced url in cloudfirestore. Uploading and showing the file in the app works perfectly.
But when i try to delete an image, i get an error:
"[firebase_storage/object-not-found] No object exists at the desired reference."
I found out that the urls in firebasestorage and in cloudfirestore are not the same:
FirebaseStorage URL: https://firebasestorage.googleapis.com/v0/b/project-db68d.appspot.com/o/images%2FNvbKO7fZxv5KXsPy1lPJovsxiKXN%2Fimage_cropper_1662715164516_out.jpg?alt=media&token=2d591f0d-d2ee-4640-8133-57cea509d3d7 //Does not show the file in the browser
CloudFirestore URL: gs://project-db68d.appspot.com/images/NvbKO7fZxv5KXsPy1lPJovsxiKXN/image_cropper_1662715164516_out.jpg // Shows the file in der browser
I don`t understand why 2 different urls are created and how to fit it, when i print the url it shows the url from firestorage?
This is my code:
Iam working with ImagePicker, flutter_image_compress and image_cropper, latest versions flutter and packages
Future<File?> getImageFromCamera()async{
File receivedImageFromCamera = await _pickImageFromDevice.pickSingleImageFromGallerieOrCamera(ImageSource.camera);
File receivedCroppedImage = await _croppImageFromDevice.imageCropper(receivedImageFromCamera);
File? compressedFile = (await _imageCompressor.compressFile(receivedCroppedImage));
return compressedFile;
}
static Future<String> uploadFile(String destination,File file)async{
final ref = FirebaseStorage.instance.ref(destination);
final result = await ref.putFile(file);
final String fileUrl = (await result.ref.getDownloadURL()).toString();
return fileUrl;
}
if(compressedFile==null) return;
final fileName = basename(compressedFile.path);
final destination = 'images/$chatId/$fileName';
final fileUrl = await UploadFileToStorage.uploadFile(destination,compressedFile);
Both URLs are valid references to the file, but they have a different protocol. The gs:// protocol is specific to Google Cloud Storage, and is supported by very few clients. The https:// protocol is universal and supported almost everywhere.
I have a machine learning model that is saved as .h5 and used in a flask server. The server is supposed to take an audio file as input and return a prediction string.
My Flask server code:
#app.route("/predict", methods=["POST"])
def predict():
# get file from POST request and save it
audio_file = request.files["file"]
file_name = str(random.randint(0, 100000)) # generate file name as a dummy random number
#wav_filename = str(random.randint(0, 100000))
audio_file.save(file_name)
# instantiate keyword spotting service singleton and get prediction
kss = Keyword_Spotting_Service() # Where our model is hold
predicted_emotion = kss.predict(file_name)
# we don't need the audio file any more - let's delete it!
os.remove(file_name)
# send back result as a json file (dictionary)
result = {"emotion": predicted_emotion}
return jsonify(result)
I tested my server using python client and it worked.
in my flutter app I created a predict method:
final uri = Uri.parse('http://192.168.1.14:5000/predict');
final request = new http.MultipartRequest("POST", uri);
request.fields['audio'] = "audio";
//myStreamController.stream.asBroadcastStream().listen(request);
final multipartFile = new http.MultipartFile.fromBytes('file', (await rootBundle.load("assets/audioFile.wav")).buffer.asUint8List( ), filename: 'audioFile.wav');
request.files.add(multipartFile);
request.headers["Content-Type"] = 'multipart/form-data';
final streamedResponse = await request.send();
// final x = await streamedResponse.stream.toBytes();
Response response = await http.Response.fromStream(streamedResponse);
Map<String, dynamic> result = jsonDecode(response.body);
var resultx = jsonDecode(json.encode(response.body));
predic = "${resultx['emotion']}";
// resultx.clear();
return predic;
It keeps giving me this error: File contains data in an unknown format (Runtime Error).
What am I missing?
Any help will be highly appreciated.
I want to check an online txt file for the newest version code and show a dialog which says "Please update" or something similar. Is it posiible to put the content of the file into a variable?
EDIT: I tried Arpit Awasthi's solution but I get these errors:
lib/main.dart:685:25: Error: Method not found: 'HttpClient'.
var request = await HttpClient().getUrl(Uri.parse(url));
^^^^^^^^^^
lib/main.dart:687:23: Error: Method not found: 'consolidateHttpClientResponseBytes'.
var bytes = await consolidateHttpClientResponseBytes(response);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/main.dart:688:5: Error: 'Directory' isn't a type.
Directory appDocDir = await getApplicationDocumentsDirectory();
^^^^^^^^^
lib/main.dart:690:5: Error: 'File' isn't a type.
File file = File("${appDocDir.path}/$fileName");
^^^^
lib/main.dart:690:17: Error: Method not found: 'File'.
File file = File("${appDocDir.path}/$fileName");
^^^^
lib/main.dart:691:5: Error: 'File' isn't a type.
File urlFile = await file.writeAsBytes(bytes);
^^^^
You can use the following function to download the file and then get the File object of that file.
static downloadFile(String url) async{
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
Directory appDocDir = await getApplicationDocumentsDirectory();
String fileName = ('yourFileName.fileExtention');
File file = File("${appDocDir.path}/$fileName");
File urlFile = await file.writeAsBytes(bytes);
return urlFile;
}
Note :- I've used this plugin to get app folder path :- path_provider: ^1.6.18
Basically, what you can do is the following.
You May Define in a variable (context probably) you Current Version...
The you a async http request, you can call to an API where you check your latest release and if it is > that current one, trigger an alert dialog that shows that There is a new version available.
I am creating a to-do list app with flutter, and I want my users to be able to back-up their tasks on google drive.
This is the code I'm using:
// Create the file we want to upload.
ga.File fileToUpload = ga.File();
var file = await _localFile;
fileToUpload.parents = ["appDataFolder"];
fileToUpload.name = path.basename(file.absolute.path);
// Create a new back-up file on google drive.
var response = await drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
// Get the file id.
fileId = response.id;
The problem is that every time I get a different file id and I need to retrieve the file
from google drive with the same file id all the time and not with a different id every time.
I've tried using the update method instead of the create method:
ga.File fileToUpload = ga.File();
var file = await _localFile;
fileToUpload.parents = ["appDataFolder"];
fileToUpload.name = path.basename(file.absolute.path);
drive.files.update(fileToUpload, fileId);
But I get Unhandled Exception: DetailedApiRequestError(status: 403, message: The parents field is not directly writable in update requests. Use the addParents and removeParents parameters instead.)
I also tried to set the file id before using the create method:
fileToUpload.id = fileId;
await drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
But then I get Unhandled Exception: DetailedApiRequestError(status: 400, message: The provided file ID is not usable.)
Or that a file with that id is already exists.
So I've tried to delete the file from google drive and then create it again with the same id:
fileToUpload.id = fileId;
drive.files.get(fileId).then((value) {
if (value != null) {
drive.files.delete(fileId).then((value) {
drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
});
} else {
drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
}
});
But then I also get Unhandled Exception: DetailedApiRequestError(status: 400, message: The provided file ID is not usable.)
Even though I'm using the same file id given by google drive for the original file.
Any solution?
What you need to first check if the file is present in the drive by the name. Since there is not direct API to fetch a file with a name from google drive, you need to make use of the List api and get the files first before checking their name
For that you can use the following query
{
q: `'appDataFolder' in parents and trashed = false`
}
Once you get the response you can check if your file is present by name. If its get its id and trigger an update call for the file.
Note: you do not pass parents key to upload but addParents
For media upload you would use the following url
PATCH https://www.googleapis.com/upload/drive/v3/files/fileId
If you do not find the file, you go by the method of creating a new one
// Create the file we want to upload.
ga.File fileToUpload = ga.File();
var file = await _localFile;
fileToUpload.parents = ["appDataFolder"];
fileToUpload.name = path.basename(file.absolute.path);
// Create a new back-up file on google drive.
var response = await drive.files.create(
fileToUpload,
uploadMedia: ga.Media(file.openRead(), file.lengthSync()),
);
If you want to set the id of the file you have to use a generated id from google. That's why you're getting the provided file ID is not usable. Theres's a class you can use called generateIds which you can use to create id's that can be used with create requests as you've done above. The Google Drive API developer website has a tool where you can make requests to the api. It's called "Try it now"(like postman) For example, create the list of ids(just press execute) here. Pick one of the ids and add it to the request body (in the request body box on the left side , press the plus sign to get the id key and add the generatedId) here . You should get a 200 response with the id you sent with the request. It will also return a specific error message that you can handle if the id already exists (code 409)
you don't have to specify the
fileToUpload.parents = ["appDataFolder"];
while updating a file in google drive