how to get download URL after image insertion into firebase.storage - xamarin.android

I am able to insert the image to firebase.storage but the download link I get is not the same download link attached to the image when it is uploaded.
public void UploadImage()
{
if (filePath != null)
progressBar.Visibility = ViewStates.Visible;
var images = storageRef.Child("profilePicture");
images.PutFile(filePath);
}
void IOnSuccessListener.OnSuccess(Java.Lang.Object result)
{
var snapShot = (UploadTask.TaskSnapshot)result;
var downloadURL = snapShot.DownloadUrl.Scheme
+ ":" + snapShot.DownloadUrl.SchemeSpecificPart;
}
UserData newUser = new UserData();
newUser.UserId = UserId;
newUser.Email = UserEmail;
newUser.FirstName = first.Text;
newUser.LastName = last.Text;
newUser.MobileNumber = phone.Text;
newUser.Userprofile = storageRef.DownloadUrl;

I can share native Android & IOS code to get URL from Firebase uploaded image/file, may be you could get some help from that for Xamarin.
Android:
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return fileRef.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String stringUrl = downloadUri.toString(); // Image url
} else {
// Handle failures
Log.e("oops","problem occurred");
}
}
});
IOS:
fileRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
print("Uh-oh, an error occurred! in url downloading")
return
}
print("downloadurl: \(downloadURL.absoluteString)");
}

Related

Swift Firebase Storage get all Download URL's of a specific child

Currently, I can fetch the download url by file name via firebase storage reference.
I would like to retrieve all download URLS in a specific child without using a file name and only using the last child name.
Simply adding every download url in a list/array
How can I accomplish this with my given reference.
func getDownloadURL() {
let ref = Storage.storage().reference()
let fileName = "Lessons_Lesson1_Class1.mp3"
let starsRef = ref.child("Daily Meditations").child("Lessons").child("Lesson 1").child(fileName)
// Fetch the download URL
starsRef.downloadURL { url, error in
if let error = error {
// Handle any errors
print(error)
} else {
// Get the download URL for 'Lessons_Lesson1_Class1.mp3'
print(url)
}
}
}
Firebase Refrence Docs
let stg = Storage.storage().reference()
let path = "Daily Meditations/Lessons/Lesson 1"
stg.child(path).listAll { (list, error) in
if let error = error {
print(error)
} else {
let inStorage = list.items.map({ $0.name })
print(inStorage) // an array of file names in string format
}
}
I assume spaces are allowed in path names since you're using them. To list all of the files in a path, use listAll. The method will return a StorageListResult object which I've named list.
https://firebase.google.com/docs/reference/swift/firebasestorage/api/reference/Classes/StorageListResult
So I was able to combine List all files and Download URL to achieve what I was trying to accomplish from the firebase documentation.
Here is the code:
func getDownloadURl() {
let ref = Storage.storage().reference()
let storageReference = ref.child("Lessons/Lesson 1")
storageReference.listAll { (result, error) in
if let error = error {
print(error)
}
for item in result.items {
//List storage reference
let storageLocation = String(describing: item)
let gsReference = Storage.storage().reference(forURL: storageLocation)
// Fetch the download URL
gsReference.downloadURL { url, error in
if let error = error {
// Handle any errors
print(error)
} else {
// Get the download URL for each item storage location
print(url!)
}
}
}
}
}
If anyone is using with VUE 2.6 and TS, here is my workaround
Imports
import {
getStorage,
ref,
getDownloadURL,
listAll,
StorageReference,
} from "firebase/storage";
async mounted(): Promise<void> {
const storage = getStorage();
const imageRefs = await listAll(ref(storage, "SOME BUCKET"))
.then((refs) => {
return refs.items;
})
.catch((error) => {
// Handle any errors
});
(imageRefs as StorageReference[]).forEach((item) => {
console.log(item);
getDownloadURL(item).then((downloadURL) => {
console.log(downloadURL);
this.model.listFiles.push(downloadURL);
});
});
console.log(imageRefs);
console.log(this.model.listFiles);
},

How to get download progress in the Google Drive API (Swift 5)

I use this function to download file from the Google Drive API and I want to get download progress. Maybe anybody knows how to do it?
func download(file: GTLRDrive_File) {
let url = "https://www.googleapis.com/drive/v3/files/\(file.identifier!)?alt=media"
let fetcher = drive.fetcherService.fetcher(withURLString: url)
fetcher.beginFetch(completionHandler: { data, error in
if let error = error {
print(error.localizedDescription)
}
//Here I save data to the Documents
})
}
I tried to get it from fetcher.receivedProgressBlock but it's always return nil
Solution. Actual for Swift 5:
func download(file: GTLRDrive_File) {
let fileSize = file.size?.doubleValue //You need to fetch file size in your request q.fields = "kind,nextPageToken,files(mimeType,id,name,size)"
let url = "https://www.googleapis.com/drive/v3/files/\(file.identifier!)?alt=media"
let fetcher = drive.fetcherService.fetcher(withURLString: url)
fetcher.beginFetch(completionHandler: { data, error in
if let error = error {
print(error.localizedDescription)
}
//Here I save data to the Documents
})
//Here you can get total bytes received (value is updated in real time)
fetcher.receivedProgressBlock = { _, totalBytesReceived in
guard let fileSize = fileSize else { return }
let progress = Double(totalBytesReceived) / fileSize
print(progress) //Here you can update UI (progress bar) or do something else
}
}
For some reason, file.size returns nil so I used fetcher.response?.expectedContentLength instead.
func download(file: GTLRDrive_File, service: GTLRDriveService) {
let url = "https://www.googleapis.com/drive/v3/files/\(file.identifier!)?alt=media"
let fetcher = service.fetcherService.fetcher(withURLString: url)
fetcher.beginFetch(completionHandler: { fileData, error in
if error == nil {
print("finished downloading file Data...")
print(fileData as Any)
// do anything with data here
} else {
print("Error: \(error?.localizedDescription)")
}
})
fetcher.receivedProgressBlock = { _, totalBytesReceived in
print("totalBytesReceived: \(totalBytesReceived)")
print("size: \(fetcher.response?.expectedContentLength)")
if let fileSize = fetcher.response?.expectedContentLength {
let progress: Double = Double(totalBytesReceived) / Double(fileSize)
print(progress)
// Update progress bar here
}
}
}

Swift: Downloading Images from DropBox

Here's the code I've tried so far:
client?.files.download(path: "/AlloyTest/\(imageName)").response { response, error in
if let response = response {
let responseMetadata = response.0
print(responseMetadata)
let fileContents = response.1
print(fileContents)
} else if let error = error {
print(error)
}
}
.progress { progressData in
print(progressData)
}
This is the error I'm getting when trying the function below:
API route error - {
".tag" = path;
path = {
".tag" = "not_found";
};
}
NEW CODE
func getImage(imageName: String, completion: #escaping (UIImage, NetworkingError) -> ()) {
// Get Image from dropbox
// Download to Data
client?.files.listFolder(path: "/AlloyTest").response { response, error in
if let response = response {
let entries = response.entries
print("ENTRIES:", entries)
} else if let error = error {
print(error)
}
}
}
A path/not_found error indicates that there was nothing at the specified path, in this case "/AlloyTest/\(imageName)", in the connected Dropbox account. Make sure you provide the correct path.
For example, you can list the contents of any particular folder to get the correct path values of its contents using listFolder/listFolderContinue. The path for any particular returned item is Metadata.pathLower.

ambigouous reference to member 'datatask(with:completionhandler:)'

I'm having a problem with my code. I am trying to download a picture through a StringBuilder and then set it to a UIImage I seem to get a problem and I hope someone can see what I have done wrong.
setUI:
uiMovieTitle.text = self.movies![movieIndex].title
var finalImageUrl = StringBuilder()
let session = URLSession(configuration: .default)
let downloadPicTask = session.dataTask(with: finalImageUrl) { (data, response, error) in
// The download has finished.
if let e = error {
print("Error downloading cat picture: \(e)")
} else {
// No errors found.
// It would be weird if we didn't have a response, so check for that too.
if let res = response as? HTTPURLResponse {
print("Downloaded cat picture with response code \(res.statusCode)")
if let imageData = data {
// Finally convert that Data into an image and do what you wish with it.
let image = UIImage(data: imageData)
// Do something with your image.
uiMoviePoster.image = image
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
downloadPicTask.resume()
}
StringBuilder
func StringBuilder() -> (String){
let posterBase = "http://image.tmdb.org/t/p/w1920"
let linkEnd = self.movies?[movieIndex].posterPath
var finalLink = ""
finalLink = posterBase + linkEnd!
return finalLink
}
I do also have another download which gets me a list of movies(JSON) and is crucial for the StringBuilder.
The compiler is complaining because the function SwiftBuilder returns a String and there are multiple methods on URLSession named dataTask(with:completion:), but none of them take a String for the first argument.
If you need SwiftBuilder to continue to return a string for some other part of your code, then for here you'll need to convert that string to a URL.
Something like the following should work:
let session = URLSession(configuration: .default)
let imageUrlString = StringBuilder()
if let imageUrl = URL(string: imageUrlString) {
let downloadPicTask = session.dataTask(with: imageUrl) { (data, response, error) in
// The download has finished.
And so on... let me know if that makes sense.

Dropbox usersGetCurrentAccount no member compiler error

Using IOS 9.1, running on Xcode 7.1.1. under El Capitan. I am trying out the tutorial on accessing dropbox thru their (new maybe) SwiftDropbox library by following this page.
https://blogs.dropbox.com/developers/2015/05/try-out-swiftydropbox-the-new-swift-sdk-for-dropbox-api-v2/
Started well, managed to connect and get authorised, but unable to do much more cause the code posted to their tutorial doesn't compile.
if let client = Dropbox.authorizedClient {
// Get the current user's account info
client.usersGetCurrentAccount().response { response, error in
if let account = response {
println("Hello \(account.name.givenName)")
} else {
println(error!)
}
}
// List folder
client.filesListFolder(path: "").response { response, error in
if let result = response {
println("Folder contents:")
for entry in result.entries {
println(entry.name)
}
} else {
println(error!)
}
}
Complaining that DropboxClient has no member "usersGetCurrentAccount" or "filesListFolder" which I assume are some sort method calls {pretty new to swift too}. Can not seem to google any useful leads on this? What should this code read/say?
Bon,
THANKYOU smarx; you put me on the right path. Here is the final code; with two minor fixes to the tutorial he mentioned here.
// ViewController.swift
import UIKit
import SwiftyDropbox
class ViewController: UIViewController {
#IBAction func linkButtonPressed(sender: AnyObject) {
if (Dropbox.authorizedClient == nil) {
Dropbox.authorizeFromController(self)
} else {
print("User is already authorized!")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Verify user is logged into Dropbox
if let client = Dropbox.authorizedClient {
// Get the current user's account info
client.users.getCurrentAccount().response { response, error in
print("*** Get current account ***")
if let account = response {
print("Hello \(account.name.givenName)!")
} else {
print(error!)
}
}
// List folder
client.files.listFolder(path: "").response { response, error in
print("*** List folder ***")
if let result = response {
print("Folder contents:")
for entry in result.entries {
print(entry.name)
}
} else {
print(error!)
}
}
// Upload a file
let fileData = "Hello!".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
client.files.upload(path: "/hello.txt", body: fileData!).response { response, error in
if let metadata = response {
print("*** Upload file ****")
print("Uploaded file name: \(metadata.name)")
print("Uploaded file revision: \(metadata.rev)")
// Get file (or folder) metadata
client.files.getMetadata(path: "/hello.txt").response { response, error in
print("*** Get file metadata ***")
if let metadata = response {
if let file = metadata as? Files.FileMetadata {
print("This is a file with path: \(file.pathLower)")
print("File size: \(file.size)")
} else if let folder = metadata as? Files.FolderMetadata {
print("This is a folder with path: \(folder.pathLower)")
}
} else {
print(error!)
}
}
// Download a file
let destination : (NSURL, NSHTTPURLResponse) -> NSURL = { temporaryURL, response in
let fileManager = NSFileManager.defaultManager()
let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
// generate a unique name for this file in case we've seen it before
let UUID = NSUUID().UUIDString
let pathComponent = "\(UUID)-\(response.suggestedFilename!)"
return directoryURL.URLByAppendingPathComponent(pathComponent)
}
client.files.download(path: "/hello.txt", destination: destination).response { response, error in
//client.files.download(path: "/hello.txt").response { response, error in
if let (metadata, url) = response {
print("*** Download file ***")
let data = NSData(contentsOfURL: url)
print("Downloaded file name: \(metadata.name)")
print("Downloaded file url: \(url)")
print("Downloaded file data: \(data)")
} else {
print(error!)
}
}
} else {
print(error!)
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You're reading a blog post from May about an early preview version of the SDK. Lots of things have changed since that post! Check out https://www.dropbox.com/developers/documentation/swift#tutorial for an up-to-date tutorial.
I believe you want users.getCurrentAccount and files.listFolder.

Resources