Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Access, Store and Share Files

You can access and modify local files, download resources at runtime and store them in the cloud with the Firebase Cloud Storage.

Open, Read, Write, Save, Copy & Remove Files with QML

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)
   }
 }

Download Files and Resources at Runtime

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:

  • You want to keep your app store binary as small as possible for the first download, to increase the download numbers of your app or game with a smaller download size.
  • You want to download additional content packages after in-app purchases.
  • Keep your initial app size below the store limits:
    • On Google Play, your initial apk size must be below 100MB, after that you need to use Android expansion files. To avoid that, you can just use DownloadableResource and download the additional files at a later time.
    • On iOS, your initial binary size limit is 150MB for mobile network downloads. If your binary is bigger, the user can only download your app over WiFi. Downloading additional resources later also helps you to avoid this limit.
    • With the Felgo DownloadableResource component, you can create a cross-platform solution to work with downloadable resources, that works for both iOS AND Android. It even works on Desktop too, with a single source code for all platforms! This way, you do not need to deal with Android expansion files and can create a working solution for all platforms instead.

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 live 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.

Firebase Database and Firebase Cloud Storage

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.

Upload Local Files to the Firebase Cloud Storage

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."
           }
         })
       }
     }
   }
 }
Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded