PhantomAppDevelopment / firebase-as3

Integrate Firebase Auth, Realtime Database and Storage in your Adobe AIR projects.
MIT License
55 stars 12 forks source link

Image Upload in FlashPlayer #16

Open veselekov opened 7 years ago

veselekov commented 7 years ago

Hi,

I am new to GitHub. So I don't think this should go here. But I found this works for uploading an image using flashplayer as opposed to AIR (i.e. no 'fileReference.uploadUnencoded()'). Useful if you are doing a web based app and don't wanna use java etc. Might wanna add this to the Upload example code section.

var appID:String = "YOUR-APP-ID";

public function uploadFile(): void {
            var fileRef: FileReference = new FileReference();
            var fileFilter: FileFilter = new FileFilter("Images", "*.jpg");
            fileRef.addEventListener(Event.SELECT, fileSelected)
            fileRef.browse([fileFilter]);
            function fileSelected(event: Event): void {
                fileRef.addEventListener(Event.COMPLETE, onFileLoaded);
                fileRef.addEventListener(IOErrorEvent.IO_ERROR, ioError);
                fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress);
                fileRef.load();
            }
            function onFileLoaded(event: Event): void {
                var fr: FileReference = event.target as FileReference;
                var data: ByteArray = fr["data"];
                fileRef.removeEventListener(Event.COMPLETE, onFileLoaded);
                fileRef.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
                fileRef.removeEventListener(ProgressEvent.PROGRESS, onProgress);

                var request: URLRequest = new URLRequest("https://firebasestorage.googleapis.com/v0/b/"+appID+".appspot.com/o/ArtWorks%2F" + fr.name);
                request.method = URLRequestMethod.POST;
                request.data = data;

                var loader: URLLoader = new URLLoader();
                loader.addEventListener(flash.events.Event.COMPLETE, uploadComplete);
                loader.addEventListener(flash.events.IOErrorEvent.IO_ERROR, ioError);
                loader.load(request);
            }

            function uploadComplete(event:Event):void{
                trace("upload complete")
            }

            function ioError(event: IOErrorEvent): void {
                trace("ioError")
            }
            function onProgress(event: ProgressEvent): void {
                trace(event.bytesLoaded + "/" + event.bytesTotal);
            }
        }
agentphantom commented 7 years ago

Thank you for sharing this!

I actually tried to use Firebase database in a Flash Player project but for some reason I wasn't able to connect to it. That's why I ditched the idea of using Firebase on Flash Player altogether.

Since Firebase Storage is actually Google Cloud Storage it might be the reason that one works well on the Flash Player.

veselekov commented 7 years ago

@agentphantom I haven't tried using it through the web. But I was able to get an upooad happening through flash player on desktop. Might require some crossdomain exceptions

veselekov commented 7 years ago

More progress on the Flash Player based code. You will need to use a phpProxy such as the one attached and affix the upload URL on your website to your Firebase url request. I've tested this with getting data from realtime database but I am still yet to be able to send.

So when you go to do a URLRequest with your firebase url do this

var phpProxy:String = "http://www.example.com/phpProxy.php?url=" //this has to be on the same website your swf is uploaded to
var appID:String = "" // YOUR APPLICATION ID

var request:URLRequest = new URLRequest(phpProxy+"https://"+appID+".firebaseio.com")
var loader: URLLoader = new URLLoader();
var rawData: Object;
loader.addEventListener(Event.COMPLETE, newsLoaded);
loader.load(request);

function newsLoaded(event:Event){
    rawData = JSON.parse(event.currentTarget.data);
    //rawData is your DB info. To access a node called 'World' just use rawData.World
}

phpProxy.php.zip

agentphantom commented 7 years ago

Very interesting. I remember doing something similar like this in the Twitter 1.0 API days.

I have been working on something similar. A port of this guide but for Python which can be used as a proxy.

https://github.com/agentphantom/firebase-python

veselekov commented 7 years ago

@agentphantom I am finding that the php works for images other than the ones used on firebase storage. Perhaps it is to do with the download tokens.

veselekov commented 7 years ago

@agentphantom So I bit of an update. The php proxy which I've attached earlier can read data from the web. But when it goes to 'PATCH' data it returns what is already there rather than updating it. I am looking into this however if you've got any suggestions seeing as you've worked through a php proxy before let me know.

Here is the php proxy at the moment:

<?php

$post_data = $HTTP_RAW_POST_DATA;

$header[] = "Content-type: text/xml";
$header[] = "Content-length: ".strlen($post_data);

$ch = curl_init( $_GET['url'] ); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

if ( strlen($post_data)>0 ){
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}

$response = curl_exec($ch);     
$response_headers = curl_getinfo($ch);     

if (curl_errno($ch)) {
    print curl_error($ch);
} else {
    curl_close($ch);
    header( 'Content-type: ' . $response_headers['content-type']);
    print $response;
}

?>

I am wondering what would be needed so that the Header will 'PATCH' data rather than just returning it.

veselekov commented 7 years ago

@agentphantom Got it working! So this has gotten a bit derailed from the original upload in flashplayer topic. But here is where I found luck at patching to Firebase So all you need is a couple of tweaks to the php and the URLRequest. Here is all you need to change.

First the PHP

<?php

$post_data = $_POST['data'];

$ch = curl_init( $_GET['url'] ); 
$header = array( "X-HTTP-Method-Override: PATCH");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

if ( strlen($post_data)>0 ){
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}

$response = curl_exec($ch);     
$response_headers = curl_getinfo($ch);     

if (curl_errno($ch)) {
    print curl_error($ch);
} else {
    curl_close($ch);
    header( 'Content-type: ' . $response_headers['content-type']);
    print $response;
}

?> 

Now for all you need to change in the URLRequest from the post earlier. All you need to do is send the data as a a URLVariable so the php can interpret it as $_POST['data']

var proxyURL:String = [URL TO PROXY ABOVE]
var directory:String = [TARGET-DIRECTORY]
var request: URLRequest = new URLRequest(proxyURL+directory + "/.json");
var urlVars:URLVariables = new URLVariables();
urlVars.data = JSON.stringify(myObject); // create this
//request.data = JSON.stringify(myObject); // Instead of sending this
request.method = URLRequestMethod.POST;
request.requestHeaders.push(header);
request.data = urlVars // so you can send this

I am going to test with Firebase storage now. But that is one way of doing it.