huuanh1987 / facebook-java-api

Automatically exported from code.google.com/p/facebook-java-api
0 stars 0 forks source link

Data Store API support #114

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
While the object storage feature is still in Beta, it is of high quality.

The new data store services which allow you to define metadata and modify
data are detailed here:
http://wiki.developers.facebook.com/index.php/Data_Store_API_documentation

Original issue reported on code.google.com by david.j....@googlemail.com on 2 Oct 2008 at 8:21

GoogleCodeExporter commented 8 years ago
I've had some success getting the createObject method working against the HEAD 
code.
The object is getting created and can be retrieved by its ID in FQL (using 
where _id
= 5002261217200). However, I can't search the FQL table based on the properties 
of
the row (where ownerfacebookid = 536286910); it returns 0 rows.

I'll continue investigating and will post a patch here when the code is better 
quality.

Original comment by david.j....@googlemail.com on 15 Oct 2008 at 8:25

GoogleCodeExporter commented 8 years ago
So, just to clarify my current problem... running the following FQL using 
Facebook's
own query tool on a table that I've already inserted data into:

select ownerfacebookid from app.item where _id = 5002261217200
> Found 1 result.
> no.   ownerfacebookid
> 1 536286910

Then running:

select ownerfacebookid from app.item where ownerfacebookid = 536286910
> Found 0 results.
> no.   ownerfacebookid

Original comment by david.j....@googlemail.com on 15 Oct 2008 at 8:30

GoogleCodeExporter commented 8 years ago
After some digging, it appears that the data store API doesn't follow the SQL 
model.

You have to define:
   * An object type to hold your item details (e.g. name, description, time added)
   * An association to link your item to a facebook user.

In SQL, you'd expect to add a foreign key to your item table. This doesn't work 
in
the data store because you have to look *everything* up by _id.

Decent explanation is here:
http://www.dereksantos.ca/?p=23

So, I'm going to change my data storage model slightly and ensure that any time 
an
item is inserted a corresponsing association is also inserted. I'll base my 
JUnit
tests around that concept.

Original comment by david.j....@googlemail.com on 16 Oct 2008 at 7:54

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Hi. I see that the code has moved on slightly for 2.0.3. There are only a 
couple of
conflicts with my patch but I'm happy to produce another updated patch if anyone
intends to get these new features into 2.0.3 ? Thanks.

Original comment by david.j....@googlemail.com on 28 Oct 2008 at 9:12

GoogleCodeExporter commented 8 years ago
Here's the patch for 2.0.3-SNAPSHOT (HEAD [trunk] as of this morning)

Original comment by david.j....@googlemail.com on 1 Nov 2008 at 10:55

Attachments:

GoogleCodeExporter commented 8 years ago
thank you! :)

just to warn you I freely modified the patch a lot. :)  But still does the same 
thing
that you had it doing.  Please review the code, to see what I did.  I might 
have been
too aggressive at compressing the code, but.. just something I've been doing 
since
there are sooo many methods, and they are pretty straight forward logic.. as 
long as
there are no typos that is :)

I had issues with the Test class for some reason (would not build), so I did not
include it, maybe I'll try it again in a sec.

This is great, and thank you.  But another pattern I'm trying to do is to add a 
"@see
url-to-wiki-docs" to the javadoc on the IFacebookRestClient interface.  That 
way we
don't have to search through the wiki site for the appropriate docs.  If you 
could
submit another patch with those that would be great, or I'll just do that when 
I get
to it.  An example would be: @see
http://wiki.developers.facebook.com/index.php/Data.createObject

thank you!!

Original comment by fern...@gmail.com on 3 Nov 2008 at 10:54

GoogleCodeExporter commented 8 years ago
The issue with the test class, was that it required a java 6 "Desktop" class. 
So I
had to comment that out, so the Test class is currently failing the test I 
suppose. :)

Also, I have setup eclipse formatters, so feel free to use Ctrl-Shift-F to 
format any
code :)

Original comment by fern...@gmail.com on 3 Nov 2008 at 10:59

GoogleCodeExporter commented 8 years ago
Thanks for adding this! I'll keep your changes in mind when creating my next 
patch
and will put together the @see links into a separate patch.

My JUnit test (which needs JUnit 4.x and Java 6) runs successfully after a small
modification to check for a null associationTime parameter in the 
data_setAssociation
method. The API spec details that if the value is not specified, Facebook 
defaults
the association time to NOW.

Index: 
facebook-java-api/src/main/java/com/google/code/facebookapi/ExtensibleClient.jav
a
===================================================================
---
facebook-java-api/src/main/java/com/google/code/facebookapi/ExtensibleClient.jav
a
(revision 392)
+++
facebook-java-api/src/main/java/com/google/code/facebookapi/ExtensibleClient.jav
a
(working copy)
@@ -1716,7 +1716,9 @@
        addParam( "obj_id1", object1Id, params );
        addParam( "obj_id2", object2Id, params );
        addParamIfNotBlank( "data", data, params );
-       addParamIfNotBlank( "assoc_time", associationTime.getTime() / 1000, params );
+       if(associationTime != null) {
+           addParamIfNotBlank( "assoc_time", associationTime.getTime() / 1000, params 
);
+       }
        callMethod( FacebookMethod.DATA_SET_ASSOCIATION, params );
    }

Original comment by david.j....@googlemail.com on 3 Nov 2008 at 11:13

GoogleCodeExporter commented 8 years ago
Here's a patch containing the @see javadoc params.

Original comment by david.j....@googlemail.com on 3 Nov 2008 at 11:36

Attachments:

GoogleCodeExporter commented 8 years ago
The test will work with Java 5 by using these lines instead of the Desktop line:

Runtime.getRuntime().exec("C:/Program Files/Internet Explorer/IEXPLORE.EXE " +
hitURL.toString());
Thread.sleep(20000); //Give the token registration a 20 second headstart

Note that you have to enter your password into the Facebook login page before 
the
code can succeed. I've therefore put in a 20 second delay. If this works for 
you then
I'll try to make it a bit more elegant. There are some Browser Opener libraries 
that
predate Java 6 that may be better than hardcoding the URL to IE! :)

Original comment by david.j....@googlemail.com on 3 Nov 2008 at 11:49

GoogleCodeExporter commented 8 years ago
yeah, I'm not happy with requiring IE, or any browser for that matter..

could you just ask a developer to give you an apikey/apisecret to test against? 
 It's
OK for any developers that want to test it to provide some test app to test 
against
right?

Original comment by fern...@gmail.com on 4 Nov 2008 at 12:53

GoogleCodeExporter commented 8 years ago
So.. looking at the code you say that is required (around assoc_time worries 
me).

1) if you look, the method that you removed - addParamIfNotBlank - is doing 
just what
you replaced it with; it adds it only if it's null.  So, I really don't trust 
what
you were testing.. or I can't trust the java compiler, which is scarier.. :)

So can you please try again without your change.. it really really should work
without any modifications, or we need to figure out why not :(

2) I'll take this opportunity to point out that I had to add the divide by 1000,
since java datetimes are milliseconds since epoch, and facebook wanted seconds 
since
epoch...  So keep that in mind for next time :)

Original comment by fern...@gmail.com on 4 Nov 2008 at 12:58

GoogleCodeExporter commented 8 years ago
next time you svn up, please be aware, I had to disable the tests in the code 
to be
able to build and deploy the latest code.. :(

We'll have to move uncomment the @Test annotation on the actual test once we 
figure
out how to run the test in a reliable manner..  I guess we can do the browser, 
just
really hoping that we don't have to complicate things. :(

Original comment by fern...@gmail.com on 4 Nov 2008 at 1:20

GoogleCodeExporter commented 8 years ago
Regarding the assoc_time. I saw the / 1000. Thanks for adding that, I just
incorrectly assumed milliseconds.

The null check is correct (promise!) because the API user should be able to pass
*null* into the API method parameter. Without the null check, the following 
snippet
throws a NullPointerException:
associationTime.getTime() / 1000

In my test case I have lines like:
client.data_setAssociation( "supports", andrewHewitt, chelsea, "Has a scarf and
everything", null );
The null parameter for the assoc_time shouldn't result in a 
NullPointerException.

So, it's probably worth removing the addParamIfNotBlank check, but the null 
check
needs to be there. Thanks.

Original comment by david.j....@googlemail.com on 4 Nov 2008 at 9:19

GoogleCodeExporter commented 8 years ago
The JUnit test side of things sounds like it's a wider issue of:
   * How do we test method calls that need a session?
   * What do we want to use as a test environment (i.e. API key and Secret)? If we
can get a special development one then fine; I guess I can request that on the 
main
facebook forum?

By the way, I wouldn't advocate putting JUnit tests around every API method! 
Most of
what the code is doing is simply wrapping the web service and doesn't warrant
testing. However, I'm sure you'll agree it's useful to be able to add JUnits if
anyone wants to for specific system level tests.

My approach to validating the session token was to boot up a browser. We can do 
that
without using Java 6 by importing a 3rd party library that decides how to open a
browser on the operating system being used. However, my preference would be to
specify using Maven that the project should be built with Java 5 source and 
target
code but should be compiled *by* a Java 6 compiler. This would mean that we can 
still
use the API with Java 5 JREs but that developers should be using Java 6 to run 
unit
tests. If that's acceptable to you then I'll investigate how to configure 
pom.xml to
do just that.

Alternatively, I could investigate the possibility of validating a session token
without invoking a browser. Perhaps the JUnit test could invoke HTTP calls to
Facebook and, as long as we have a configured username and password, 
authenticate.
This ties in with having a test account. If we can get a test API_KEY, SECRET,
username and password then this approach may be the best one.

For this particular issue, my main priority has already been solved; I wanted 
the
source code example of how to use the data store API and FQL available to users.
You've already checked in the code so users at least have this benefit even if 
we
can't run the test.

Original comment by david.j....@googlemail.com on 4 Nov 2008 at 9:37

GoogleCodeExporter commented 8 years ago
Please do change the relevant lines in ExtensibleClient to:

if(associationTime != null) {
    addParam( "assoc_time", associationTime.getTime() / 1000, params );
}

Without this, users need to work around the fact that they can't specify null 
as the
associationTime parameter and must use "new Date()" as it's value.

Original comment by david.j....@googlemail.com on 16 Nov 2008 at 10:44

GoogleCodeExporter commented 8 years ago
ok. finally applied the fix. thank you.

Original comment by fern...@gmail.com on 18 Nov 2008 at 4:14

GoogleCodeExporter commented 8 years ago
Super. Verified. Please go ahead and close this issue.

Original comment by david.j....@googlemail.com on 18 Nov 2008 at 9:59