Forums

OverviewFelgo 2 Support (Qt 5) › Using DownloadableRessource with user protected firebase storage

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #22775

    David

    Hello,

    I want to save files in firebase storage which are protected with the rules system from firebase. For example a path like /users/{userId}/test/test.pdf.

    I use followed firebase storage rules:

    service firebase.storage {
      match /b/{bucket}/o {
        match /{imageName} {
          allow read;
        }
        match /users/{userId}/{allPaths=**} {
          allow read: if request.auth.uid == userId;
        }
      }
    }

     

    Additionally, I save the http-requests for the files in the rtdb from firebase in the user values. That means the user has to log in in the app and then has access to the http requests. To download the files in the app, I use the DownloadableResource.

    Now the problem, If I try to download the files in the user path, it doesn’t work. If I try to download a file in the root path it works. What am I doing wrong?

    Thank you,

    David

    #22792

    Alex
    Felgo Team

    Hi David,

    can you share 2 example URLs, one that does work and one that does not? You can mask out any confidential information, I am mainly interested in the structure and special chars used in the URLs.

    Cheers,
    Alex

    #22794

    David
    #22800

    Alex
    Felgo Team

    Yes that was also my first guess. I have just created a workaround using a small C++ helper class.

    Here is a little context for the issue:

    • The path returned from the firebase upload function is of type string
    • The “source” property of the image is of type url, so internally a QUrl
    • When passing this string to the “source” property, it is converted to a url automatically, using the appropriate constructor, which ALWAYS will perform url encoding, so the %2F is effectively decoded to a /, which breaks the url

    So the proposed workaround here is:

    QUrl has a method to create a url from a string that is already encoded (which is the case for us), namely: https://doc.qt.io/qt-5/qurl.html#fromEncoded

    1. Take the string type url and pass it to a helper class
    2. This helper class creates a url from the string using the fromEncoded method and returns it
    3. Use the return url in your QML code, e.g. set it as image source

    Here are the relevant code parts:

    firebaseurlhelper.h

    #ifndef FIREBASEURLHELPER_H
    #define FIREBASEURLHELPER_H
    
    #include <QObject>
    #include <QUrl>
    
    class FirebaseUrlHelper : public QObject
    {
      Q_OBJECT
    public:
      explicit FirebaseUrlHelper(QObject *parent = nullptr);
    
    signals:
    
    public slots:
    
      QUrl fromDownloadUrl(const QString &path);
    };
    
    #endif // FIREBASEURLHELPER_H
    

    firebaseurlhelper.cpp

    #include "firebaseurlhelper.h"
    
    FirebaseUrlHelper::FirebaseUrlHelper(QObject *parent) : QObject(parent)
    {
    
    }
    
    QUrl FirebaseUrlHelper::fromDownloadUrl(const QString &path)
    {
      return QUrl::fromEncoded(path.toUtf8());
    }
    

    main.cpp

    #include <QApplication>
    #include <FelgoApplication>
    
    #include <QQmlApplicationEngine>
    
    #include "firebaseurlhelper.h"
    
    // uncomment this line to add the Live Client Module and use live reloading with your custom C++ code
    //#include <FelgoLiveClient>
    
    
    int main(int argc, char *argv[])
    {
      QApplication app(argc, argv);
      FelgoApplication felgo;
    
      // Use platform-specific fonts instead of Felgo's default font
      felgo.setPreservePlatformFonts(true);
    
      // Make this new type available in QML.
      // You could also use a context property instead, more info here: https://felgo.com/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml
      qmlRegisterType<FirebaseUrlHelper>("com.felgo.firebaseurlhelper", 1, 0, "FireBaseUrlHelper");
    
      QQmlApplicationEngine engine;
      felgo.initialize(&engine);
    
      // Set an optional license key from project file
      // This does not work if using Felgo Live, only for Felgo Cloud Builds and local builds
      felgo.setLicenseKey(PRODUCT_LICENSE_KEY);
    
      // use this during development
      // for PUBLISHING, use the entry point below
      felgo.setMainQmlFileName(QStringLiteral("qml/Main.qml"));
    
      // use this instead of the above call to avoid deployment of the qml files and compile them into the binary with qt's resource system qrc
      // this is the preferred deployment option for publishing games to the app stores, because then your qml files and js files are protected
      // to avoid deployment of your qml files and images, also comment the DEPLOYMENTFOLDERS command in the .pro file
      // also see the .pro file for more details
      // felgo.setMainQmlFileName(QStringLiteral("qrc:/qml/Main.qml"));
    
      engine.load(QUrl(felgo.mainQmlFileName()));
    
      // to start your project as Live Client, comment (remove) the lines "felgo.setMainQmlFileName ..." & "engine.load ...",
      // and uncomment the line below
      //FelgoLiveClient client (&engine);
    
      return app.exec();
    }
    

    Main.qml

    import Felgo 3.0
    import QtQuick 2.0
    
    import com.felgo.firebaseurlhelper 1.0
    
    App {
    
      NavigationStack {
    
        Page {
          title: qsTr("Main Page")
    
          Image {
            source: firebaseUrlHelper.fromDownloadUrl("https://firebasestorage.googleapis.com/v0/b/project.appspot.com/o/users%2Fklegsz6x41Ob5BVn6wWzQfdhhk73%2Fbills%2Fdummy.pdf?alt=media&token=20a2e8d9-e84b-4208-a975-d30b9a77ec37")
            anchors.centerIn: parent
            onSourceChanged: console.debug("source changed" + source)
          }
    
          FireBaseUrlHelper {
            id: firebaseUrlHelper
          }
        }
    
      }
    }
    

     

    Note: To use QML live code reloading together with custom C++, refer to: https://felgo.com/updates/release-2-16-1-live-code-reloading-with-custom-c-and-native-code-for-qt

     

    I hope this helps you solve the issue.

     

    Cheers,
    Alex

     

    #22807

    David

    Thank you very much

Viewing 5 posts - 1 through 5 (of 5 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support