You can access and modify local files, download resources at runtime and store them in the cloud with the Firebase Cloud Storage.
The FileUtils item is available as a context property from all QML components when Felgo is imported via import Felgo
. It is accessible as the FileUtils
singleton. It encapsulates methods that allow to read, write and list files.
This is an example to download a PDF file and then open it with the native PDF viewer application, using FileUtils::openFile(). It also uses the DownloadableResource type to download a pdf from a web location and store it on the device.
You can open PDFs with the native viewer application using FileUtils::openFile(). If you need to embed a PDF browser in your app instead, contact us.
import Felgo import QtQuick App { id: app // uncomment this to remove the resources on startup, so you can test the downloading again //Component.onCompleted: pdfResource.remove() NavigationStack { AppPage { title: "Download PDF" Column { anchors.centerIn: parent AppButton { text: "Download / Open" onClicked: { if(pdfResource.available) openPdf() else pdfResource.download() } } AppText { text: "Status: " + pdfResource.status } } } } DownloadableResource { id: pdfResource source: "http://www.orimi.com/pdf-test.pdf" storageLocation: FileUtils.DocumentsLocation storageName: "pdf-test.pdf" extractAsPackage: false // if the download is competed, available will be set to true onAvailableChanged: if(available) openPdf() } function openPdf() { // you can also open files with NativeUtils.openUrl() now (for paths starting with "file://") //NativeUtils.openUrl(pdfResource.storagePath) FileUtils.openFile(pdfResource.storagePath) } }
DownloadableResource allows downloading app resources on demand during runtime. That way not all resources must be included in the app binary and therefore result in smaller downloads from the app stores. As shown in the example above, it can also be used to download content files from the web, thus you can use it for file sharing apps. An even better fit for file sharing is the Firebase Cloud Storage.
The most popular use cases for downloadable packages are:
Here is a small example how you could use it: it downloads and extracts a zip archive including an image to the default location after 5 seconds. Then it replaces the placeholder image with the downloaded image:
import Felgo import QtQuick App { // uncomment this to remove the resources on startup, so you can test the downloading again //Component.onCompleted: resource1.remove() // after 5 seconds, we download the resources Timer { running: true interval: 5000 onTriggered: { resource1.download() } } NavigationStack { AppPage { title: "Downloadable Resource" DownloadableResource { id: resource1 extractAsPackage: true // true for zip archives source: "https://felgo.com/web-assets/girl.zip" } AppImage { width: parent.width fillMode: AppImage.PreserveAspectFit // as long as the resource file is not available, we use a placeholder image // (the example placeholder is actually also from a web url, to be usable with the web editor) // if the resource is available, we get the extracted file url and set it as new image source // on your next app start (or code reload) the resource will be available immediately and not downloaded again source: resource1.available ? resource1.getExtractedFileUrl("girl.jpg") : "https://felgo.com/web-assets/balloon.png" } } } }
DownloadableResource can load files from any HTTP(S)
web addresses. You can add a secret to protect and
restricts downloads to your app or game only. You can download single files or entire .zip
-archives, which are automatically extracted for further usage.
The item downloads and extracts to a standard path or custom location. You can then use downloaded resources from within your app or game as you do with local resources.
The Firebase plugin allows to use the Firebase backend services. FirebaseAuth provides e-mail authentication to create user accounts, log in and log out. You can access the FirebaseDatabase and store and retrieve user-specific data with and without authentication. Use FirebaseStorage to upload binary files to the cloud.
With the FirebaseStorage item you can upload files to the Firebase Cloud Storage. It uploads local files to the cloud file system and returns the public download URL. With Firebase, you can create content sharing apps like Facebook or Snapchat without additional server-side code.
Examples for local files you can upload are:
Here is a code example, that shows how to upload an image taken with the camera. After the image is uploaded, we display it in the app.
import QtQuick import Felgo App { NavigationStack { FlickablePage { title: "Firebase Storage" flickable.contentHeight: column.height FirebaseStorage { id: storage config: FirebaseConfig { projectId: "v-play-live-client-test-db" databaseUrl: "https://v-play-live-client-test-db.firebaseio.com" storageBucket: "v-play-live-client-test-db.appspot.com" //platform dependent - get these values from the google-services.json / GoogleService-info.plist apiKey: Qt.platform.os === "android" ? "AIzaSyD3Pmw89NHhdG9nGIQWwaOB55FuWjcDSS8" : "AIzaSyCheT6ZNFI4mUwfrPRB098a08dVzlhZNME" applicationId: Qt.platform.os === "android" ? "1:40083798422:android:ed7cffdd1548a7fa" : "1:40083798422:ios:ed7cffdd1548a7fa" } } Column { id: column width: parent.width anchors.margins: dp(12) AppButton { text: "Capture image + upload" onClicked: NativeUtils.displayCameraPicker() } AppText { id: status text: "Idle" } // this will display the image after it's uploaded AppImage { id: img width: parent.width fillMode: AppImage.PreserveAspectFit autoTransform: true } } } } Connections { target: NativeUtils onCameraPickerFinished: (accepted, path) => { if(accepted) { //picture taken with camera is stored at path - upload to Firebase Storage storage.uploadFile(path, "test-image" + Date.now() + ".png", function(progress, finished, success, downloadUrl) { if(!finished) { status.text = "Uploading... " + progress.toFixed(2) + "%" } else if(success) { img.source = downloadUrl status.text = "Upload completed." } else { status.text = "Upload failed." } }) } } } }