Search code examples
androidfacebookfacebook-graph-apititanium

Appcelerator Titanium: Facebook Image Upload fail


i have an error with the Image Upload from Facebook in my Titanium Software, everytime i want to upload an image from my App i get this:

Fail: REST API is deprecated for versions v2.1 and higher

But if i try the same code in the KitchenSink example app, it works perfect:

var xhr = Titanium.Network.createHTTPClient({
        onload: function() {
     // first, grab a "handle" to the file where you'll store the downloaded data
            var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
            f.write(this.responseData); // write to the file
            var blob = f.read();
            var data = {
                caption: 'behold, a flower',
                picture: blob
            };
            facebook.request('photos.upload', data, showRequestResult);
        },
        timeout: 10000
    });
    xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
    xhr.send(); 

And in my App:

function showRequestResult(e) {
    var s = '';
    if (e.success) {
        s = "SUCCESS";
        if (e.result) {
            s += "; " + e.result;
        }
    } else {
        s = "FAIL";
        if (e.error) {
            s += "; " + e.error;
        }
    }
    alert(s);
}
Ti.App.hs_stats.addEventListener('touchend', function(e){
Ti.App.hs_stats.top = 255;
var xhr = Titanium.Network.createHTTPClient({
        onload: function() {
     // first, grab a "handle" to the file where you'll store the downloaded data
            var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
            f.write(this.responseData); // write to the file
            var blob = f.read();
            var data = {
                caption: 'behold, a flower',
                picture: blob
            };
            Ti.App.fb.request('photos.upload', data, showRequestResult);
        },
        timeout: 10000
    });
    xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
    xhr.send();     
});

Solution

  • Looks like you're using the 'old' Facebook module for Appcelerator? I have image uploads working for Profiles and Pages (although Pages is a bit different, I'll explain later). Here's some quick code (I assume you already authenticated with Facebook):

     var fb = require('facebook');
     fb.appid = "xxxxxxxxxxxxxxxxx";
     var acc = fb.getAccessToken();
    
     fb.requestWithGraphPath('me/photos?access_token='+ acc, {picture:image, message: data}, "POST", showRequestResult);
    

    The image variable is just a blob - It comes directly from event.media from a gallery selection or camera intent. data is the text for your status update.

    In your tiapp.xml add these lines:

     <property name="ti.facebook.appid">xxxxxxxxxxxxxxxxx</property>
    

    and (if you're using Android and iOS - add both or just the platform you're using)

     <modules>
        <module platform="android">facebook</module>
        <module platform="iphone">facebook</module>
    </modules>
    

    Now Pages were a bit strange:

    var endPoint = 'https://graph.facebook.com/v2.1/' + pid + '/photos?access_token='+ acc;
                                                xhr.open('POST',endPoint);
                                                xhr.send({
                                                    message: data,
                                                    picture: image
                                                });
    

    You have to use an HTTP Request, as I couldn't get the requestWithGraphPath() to work with pages no matter what I tried.

    pid is your page ID and you can get it, or a list of pages you are an admin for like so (again, create a new HTTP Request (xhr) and use this):

    xhr.open("GET","https://graph.facebook.com/v2.1/me?fields=accounts{access_token,global_brand_page_name,id,picture}&access_token=" +fb.getAccessToken());
    

    This will return the access token for each page, the global brand name (basically a clean version of the page name), it's id and the profile picture. The access token in this URL is YOUR personal access token (the &access_token= part).

    As far as I can tell, these access tokens don't expire for pages, so you can save it in your app somewhere or if you REALLY want to be safe, you could grab a token before each post, but that's a bit much.

    BONUS:

    If you want to do video posts to pages:

    var xhr = Titanium.Network.createHTTPClient();
        var endPoint = 'https://graph-video.facebook.com/'+ pid +'/videos?access_token='+ acc;
    xhr.open('POST',endPoint);
    
    xhr.setRequestHeader("enctype", "multipart/form-data");
    
    xhr.send({source:video, description:data});
    

    and for profiles:

             var acc = fb.getAccessToken();
        var xhr = Titanium.Network.createHTTPClient();
        var endPoint = 'https://graph-video.facebook.com/me/videos?access_token='+ acc;
    xhr.open('POST',endPoint);
    
    xhr.setRequestHeader("enctype", "multipart/form-data");
    
    xhr.send({source:video, description:data});
    

    video is another blob from either your camera or gallery event.media intent and data is the text you want to use for the status update.