How to use graph API with react-native-fbsdk?

2020-05-14 10:13发布

问题:

I read the document, both on github and Facebook developers docs.
There is only sample, nothing more. No API document.

The code to make a Graph API request is

const infoRequest = new GraphRequest(
  '/me',
  null,
  this._responseInfoCallback,
);

And the callback

_responseInfoCallback(error: ?Object, result: ?Object) {
  if (error) {
    alert('Error fetching data: ' + error.toString());
  } else {
    alert('Success fetching data: ' + result.toString());
  }
}

And here is the function to make a Graph API request

testRequestGraphAPI(){
  const infoRequest = new GraphRequest(
  '/me',
  null,
  this._responseInfoCallback,
  );   
    new GraphRequestManager().addRequest(infoRequest).start();
}

However, I can't find any further document. I have no idea what each parameters do.

The result for these codes above is this.

I also don't know how to get the result.

However, when I try to modify '\me' to 'me?fields=id,name', It failed. Although I have asked for permission

<LoginButton
  publishPermissions={["publish_actions,user_birthday, user_religion_politics, user_relationships, user_relationship_details, user_hometown, user_location, user_likes, user_education_history, user_work_history, user_website, user_managed_groups, user_events, user_photos, user_videos, user_friends, user_about_me, user_status, user_games_activity, user_tagged_places, user_posts, user_actions.video, user_actions.news, user_actions.books, user_actions.music, user_actions.fitness, public_profile, basic_info"]}
  onLoginFinished={
    (error, result) => {
      if (error) {
        alert("login has error: " + result.error);
      } else if (result.isCancelled) {
        alert("login is cancelled.");
      } else {
        AccessToken.getCurrentAccessToken().then(
          (data) => {
            meow_accesstoken = data.accessToken
            alert(meow_accesstoken.toString())
          }
        )
      }
    }
  }
  onLogoutFinished={() => alert("logout.")}/>  


But it does not print out what error, just object Object.

So, the problem is that I don't understand the sample code which Facebook provide with no explanation.

Here is my question that I really need you help me:
First at all, please check the javascript code that I currently looking at?
How to use graph API in react-native-fbsdk to retrieve some user information (example: full name) and successfully display it (use alert) ?
What each parameters in GraphRequest() do ?
What is the structure of error object and result object in _responseInfoCallback ?

SOLUTION
Thanks to @Samuel answer, I have updated my code

testRequestGraphAPI: function(){    
        const infoRequest = new GraphRequest(
          '/me',
          {
            parameters: {
              fields: {
                string: 'email,name,first_name,middle_name,last_name' // what you want to get
              },
              access_token: {
                string: meow_accesstoken.toString() // put your accessToken here
              }
            }
          },
          this._responseInfoCallback // make sure you define _responseInfoCallback in same class
        );
    new GraphRequestManager().addRequest(infoRequest).start();
  }

And the callback

  _responseInfoCallback: function(error: ?Object, result: ?Object) {
    alert("meow response");
    if (error) {
      alert('Error fetching data: ' + error.toString());
      console.log(Object.keys(error));// print all enumerable 
      console.log(error.errorMessage); // print error message
      // error.toString() will not work correctly in this case
      // so let use JSON.stringify()
      meow_json = JSON.stringify(error); // error object => json 
      console.log(meow_json); // print JSON 
    } else {
      alert('Success fetching data: ' + result.toString());
      console.log(Object.keys(result)); 
      meow_json = JSON.stringify(result); // result => JSON
      console.log(meow_json); // print JSON
    } 
  }

*Note: For console.log(), you need to use "Debug JS remotely" then open Chrome developer tools to see the log.

回答1:

Unfortunately the react-native-fbsdk documentation is not updated and the examples do not work well.

I got the same problem and I solved it by try and error.

To solve your problem you'll need to change your GraphRequest adding params and fields to it like this:

  <LoginButton
    onLoginFinished={
      (error, result) => {
        if (error) {
          alert("login has error: " + result.error);
        } else if (result.isCancelled) {
          alert("login is cancelled.");
        } else {

          AccessToken.getCurrentAccessToken().then(
            (data) => {
              let accessToken = data.accessToken
              alert(accessToken.toString())

              const responseInfoCallback = (error, result) => {
                if (error) {
                  console.log(error)
                  alert('Error fetching data: ' + error.toString());
                } else {
                  console.log(result)
                  alert('Success fetching data: ' + result.toString());
                }
              }

              const infoRequest = new GraphRequest(
                '/me',
                {
                  accessToken: accessToken,
                  parameters: {
                    fields: {
                      string: 'email,name,first_name,middle_name,last_name'
                    }
                  }
                },
                responseInfoCallback
              );

              // Start the graph request.
              new GraphRequestManager().addRequest(infoRequest).start()

            }
          )

        }
      }
    }
    onLogoutFinished={() => alert("logout.")}/>

You'll need to enable the Remote JS Debug to see the console.log() info. https://facebook.github.io/react-native/docs/debugging.html

And probably you need to get some permissions to get more info than names and email so it's a good idea to look the Facebook Graph API Documentation: https://developers.facebook.com/docs/graph-api/overview/

Reference:

https://github.com/facebook/react-native-fbsdk/issues/105#issuecomment-206501550



回答2:

Here is an example of a custom button if you want to make one :)

FbLoginButton() {
 LoginManager
  .logInWithReadPermissions(['public_profile'])
  .then(function (result) {
    if (result.isCancelled) {
      alert('Login cancelled');
    } else {
      AccessToken
        .getCurrentAccessToken()
        .then((data) => {
          let accessToken = data.accessToken
          alert(accessToken.toString())

          const responseInfoCallback = (error, result) => {
            if (error) {
              console.log(error)
              alert('Error fetching data: ' + error.toString());
            } else {
              console.log(result)
              alert('Success fetching data: ' + result.toString());
            }
          }

          const infoRequest = new GraphRequest('/me', {
            accessToken: accessToken,
            parameters: {
              fields: {
                string: 'email,name,first_name,middle_name,last_name'
              }
            }
          }, responseInfoCallback);

          // Start the graph request.
          new GraphRequestManager()
            .addRequest(infoRequest)
            .start()

        })
    }
  }, function (error) {
    alert('Login fail with error: ' + error);
   });
  }


回答3:

Thank you @Samuel.

I finally succeed to get user information from Facebook login because of your help!

But I struggled to figure out how can I get username and email literally from the result object cause I am a newbie in React & Javascript.

P.S. result["name"] is the point because it is object!!

So I added some code to yours for other people like me.

If you don't like using your code, just tell me that.

<LoginButton
  onLoginFinished={
    (error, result) => {
      if (error) {
        alert("login has error: " + result.error);
      } else if (result.isCancelled) {
        alert("login is cancelled.");
      } else {

        AccessToken.getCurrentAccessToken().then(
          (data) => {
            let accessToken = data.accessToken
            alert(accessToken.toString())

            const responseInfoCallback = (error, result) => {
              if (error) {
                console.log(error)
                alert('Error fetching data: ' + error.toString());
              } else {
                console.log(result)

                // Here's my code
                alert('Success fetching data: ' + result["name"].toString() + 
                ", " + result["email"].toString()); 
                /*  
                if(your DB already got this email or something unique) {
                  // SignIn()
                } 
                // when your DB doesn't have this email
                else {
                  // Do signUp() with this infomation and SignIn()
                }
                */
              }
            }

            const infoRequest = new GraphRequest(
              '/me',
              {
                accessToken: accessToken,
                parameters: {
                  fields: {
                    string: 'email,name,first_name,middle_name,last_name'
                  }
                }
              },
              responseInfoCallback
            );

            // Start the graph request.
            new GraphRequestManager().addRequest(infoRequest).start()

          }
        )

      }
    }
  }
  onLogoutFinished={() => alert("logout.")}/>


回答4:

try this

import { GraphRequest, GraphRequestManager } from 'react-native-fbsdk';

export const GetInfoUSer = () => {

return new Promise((resolve, reject) => {

    const infoRequest = new GraphRequest('/me', null, ((error, result) => {
        if (error) {
            reject(error)
        } else {
           resolve(result)
        }
    }))

    new GraphRequestManager().addRequest(infoRequest).start();

  })
}

and then

    onLoginConFacebook = () => {

    LoginManager.logInWithReadPermissions(['public_profile']).then(result => {

        if (result.isCancelled) {
            console.log(':(')
        } else {

            AccessToken.getCurrentAccessToken().then((data) => {

                let myAccessToken = data.accessToken.toString();

                GetInfoUSer().then(response => {
                    console.log(response)
                }).catch(error => {
                    console.log(error)
                })
            }
            ).catch(error => {
                console.log(':(')
            })
        }
    })
}