示例#1
0
 private IEnumerator ParseLogin()
 {
     if (FB.IsLoggedIn)
     {
         //login with Parse
         var loginTask = ParseFacebookUtils.LogInAsync(FB.UserId,
                                                       FB.AccessToken,
                                                       DateTime.Now);
         while (!loginTask.IsCompleted)
         {
             yield return(null);
         }
         //parse login completed, check results
         if (loginTask.IsFaulted || loginTask.IsCanceled)
         {
             //TODO: Parse login failure
             foreach (var e in loginTask.Exception.InnerExceptions)
             {
                 ParseException parseException = (ParseException)e;
                 Debug.Log("ParseLogin: error message " + parseException.Message);
                 Debug.Log("ParseLogin: error code: " + parseException.Code);
             }
         }
         else
         {
             Debug.Log("successfully logged into parse with FB account");
             //call FB api to get facebook name and update parse user display name if it is new or modified
             FB.API("/me", HttpMethod.GET, FBAPICallback);
         }
     }
 }
        async void ContentPanel_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                source = new CancellationTokenSource();
                fbBrowser.Visibility = Visibility.Visible;
                task = ParseFacebookUtils.LogInAsync(fbBrowser, new[] { "basic_info", "email", "user_location", "user_birthday" }, source.Token);
                await task;
                fbBrowser.Visibility = Visibility.Collapsed;

                // check to see if any fields need to be updated:
                FacebookHelper.CheckForUpdates();
                NavigationService.Navigate(new Uri("/Pages/NewsFeed.xaml?FromLogin=true", UriKind.Relative));
            }
            catch (OperationCanceledException)
            {
                task = null;
            }
            catch (Exception)
            {
                // other error:
                MessageBox.Show("There was an error trying to log in. Please try again.");
                return;
            }
        }
示例#3
0
        public async Task LoginWithFacebook(string userId, string accessToken, DateTime tokenExpiration, Action <bool> callback)
        {
            var user = await ParseFacebookUtils.LogInAsync(userId, accessToken, tokenExpiration);

            var permissions = AccessToken.CurrentAccessToken.Permissions.ToList();
            var isEmailPermissionsGranted = permissions.Any(i => i == "email");

            if (!isEmailPermissionsGranted)
            {
                AlertDialog.Builder alert;
                alert = new AlertDialog.Builder(MainActivity.AppContext);
                alert.SetTitle(AppConfig.ApplicationName);
                alert.SetMessage("Please accept all asked permissions for facebook to singup");
                alert.SetPositiveButton("OK", (senderAlert, args) => {
                });
                alert.Show();
                callback.Invoke(false);
            }
            var parameters = new Bundle();

            parameters.PutString("fields", "email, name, picture.width(500).height(500)");

            var request = new GraphRequest(
                AccessToken.CurrentAccessToken,
                "/" + userId,
                parameters,
                HttpMethod.Get,
                new FBGraphRequestCallback(callback)
                ).ExecuteAsync();
        }
 public async void OnSuccess(Object result)
 {
     // We know that this is a LoginResult
     var loginResult = (LoginResult)result;
     // Convert Java.Util.Date to DateTime
     var epoch      = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
     var expireDate = epoch.AddMilliseconds(loginResult.AccessToken.Expires.Time);
     // FB User AccessToken
     var       accessToken = loginResult.AccessToken.Token;
     ParseUser user        = await ParseFacebookUtils.LogInAsync("Your Facebook App Id", accessToken, expireDate);
 }
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            switch (resultCode)
            {
            case Result.Ok:

                string accessToken = data.GetStringExtra("AccessToken");
                string userId      = data.GetStringExtra("UserId");
                string error       = data.GetStringExtra("Exception");

                // Save access token
                var storage = SimpleStorage.EditGroup(logInDataGroup);
                storage.Put("access_token", accessToken);
                storage.Put("user_id", userId);

                fb = new FacebookClient(accessToken);


                fb.GetTaskAsync("me").ContinueWith(t => {
                    if (!t.IsFaulted)
                    {
                        var result = (IDictionary <string, object>)t.Result;
                        Console.WriteLine("entered " + t.Result);

                        string profileData = "Name: " + (string)result["name"] + "\n";


                        Task registerUser = new Task(async() => {
                            Console.WriteLine("logging in");
                            ParseUser user = await ParseFacebookUtils.LogInAsync(userId, accessToken, DateTime.Now.AddYears(1));
                            isLoggedIn     = true;
                            Finish();
                        });

                        registerUser.Start();
                    }
                });

                break;

            case Result.Canceled:
                Alert("Failed to Log In", "User Cancelled", false, (res) => {});
                break;

            default:
                break;
            }
        }
示例#6
0
        private async void LoginTile_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            try
            {
                var browser = new WebBrowser()
                {
                    Name = "browser", Width = 480, Height = 800
                };
                browserPopup.Child  = browser;
                browserPopup.IsOpen = true;
                //this.NavigationService.Navigate(new Uri("/Pages/FacebookLoginPage.xaml", UriKind.Relative));
                ParseUser user = await ParseFacebookUtils.LogInAsync(browser, null);

                var fb = new FacebookClient();
                fb.AccessToken = ParseFacebookUtils.AccessToken;
                var me = await fb.GetTaskAsync("me");

                if (user.IsAuthenticated)
                {
                    IDictionary <string, object> results = (IDictionary <string, object>)me;
                    ViewModelLocator.MainStatic.User.IsLogged      = true;
                    ViewModelLocator.MainStatic.User.FacebookId    = (string)results["id"];
                    ViewModelLocator.MainStatic.User.FacebookToken = ParseFacebookUtils.AccessToken;

                    ViewModelLocator.MainStatic.User.Username  = (string)results["name"];
                    ViewModelLocator.MainStatic.User.FirstName = (string)results["first_name"];
                    ViewModelLocator.MainStatic.User.LastName  = (string)results["last_name"];

                    ViewModelLocator.MainStatic.User.ObjectId = user.ObjectId.ToString();

                    ViewModelLocator.MainStatic.User.GetStats();

                    // available picture types: square (50x50), small (50xvariable height), large (about 200x variable height) (all size in pixels)
                    // for more info visit http://developers.facebook.com/docs/reference/api
                    string profilePictureUrl = string.Format("https://graph.facebook.com/{0}/picture?type={1}&access_token={2}",
                                                             ViewModelLocator.MainStatic.User.FacebookId,
                                                             "large",
                                                             ViewModelLocator.MainStatic.User.FacebookToken);
                    ViewModelLocator.MainStatic.User.UserImage = profilePictureUrl;
                }
                ;

                browserPopup.IsOpen = false;
            }
            catch {
                browserPopup.IsOpen = false;
            };
        }
        private async void FacebookLogin_Tapped(object sender, TappedRoutedEventArgs e)
        {
            progress.IsIndeterminate = true;

            try
            {
                var user = await ParseFacebookUtils.LogInAsync(new List <string>() { "email", "public_profile" });

                if (user != null)
                {
                    FacebookClient client       = new FacebookClient(ParseFacebookUtils.AccessToken);
                    dynamic        facebookUser = await client.GetTaskAsync("me", new { fields = "id,name,email" });

                    if (!user.Keys.Contains("nameSurname"))
                    {
                        user.Add("nameSurname", facebookUser.name);
                    }
                    else
                    {
                        user["nameSurname"] = facebookUser.name;
                    }
                    if (!user.Keys.Contains("withFacebook"))
                    {
                        user.Add("withFacebook", true);
                    }
                    if (!user.Keys.Contains("email"))
                    {
                        user.Add("email", facebookUser.email);
                    }
                    else
                    {
                        user["email"] = facebookUser.email;
                    }
                    await user.SaveAsync();

                    backgroundPanel.Visibility      = Visibility.Visible;
                    successfulLoginPanel.Visibility = Visibility.Visible;
                    NameSurname.Text = ParseUser.CurrentUser["nameSurname"] as string;
                }
            }

            catch (Exception)
            {
            }

            progress.IsIndeterminate = false;
        }
示例#8
0
        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            var auth = new OAuth2Authenticator(
                clientId: "1790522011216423",                                                 // your OAuth2 client id
                scope: "email",                                                               // the scopes for the particular API you're accessing, delimited by "+" symbols
                authorizeUrl: new Uri("https://www.facebook.com/v2.8/dialog/oauth"),          // the auth URL for the service
                redirectUrl: new Uri("https://www.facebook.com/connect/login_success.html")); // the redirect URL for the service

            auth.Completed += async(sender, eventArgs) =>
            {
                count++;
                // We presented the UI, so it's up to us to dimiss it on iOS.
                //App.SuccessfulLoginAction.Invoke();

                if (eventArgs.IsAuthenticated)
                {
                    DismissViewController(true, null);
                    var accessToken = eventArgs.Account.Properties["access_token"].ToString();
                    var expiresIn   = Convert.ToDouble(eventArgs.Account.Properties["expires_in"]);
                    var expireDate  = DateTime.Now + TimeSpan.FromSeconds(expiresIn);

                    var request  = new OAuth2Request("GET", new Uri("https://graph.facebook.com/me?fields=email,first_name,last_name,gender"), null, eventArgs.Account);
                    var response = await request.GetResponseAsync();

                    var obj = JObject.Parse(response.GetResponseText());
                    var id  = obj["id"].ToString().Replace("\"", "");
                    await ParseFacebookUtils.LogInAsync(id, accessToken, expireDate);

                    var session = await ParseSession.GetCurrentSessionAsync();

                    var token = session.SessionToken;
                    App.SuccessfulLoginAction.Invoke();
                    App.SuccessFacebookLogin(token, obj);
                }
                else
                {
                    // The user cancelled
                }
            };
            if (count <= 1)
            {
                PresentViewController(auth.GetUI(), true, null);
            }
        }
示例#9
0
        public static async Task <string> FacebookSignUp(string fbUserID, string accessToken, DateTime expiration)
        {
            try
            {
                ParseUser user = await ParseFacebookUtils.LogInAsync(fbUserID, accessToken, expiration);

                if (user == null)
                {
                    return(Constants.STR_STATUS_FAIL);
                }
                else
                {
                    return(Constants.STR_STATUS_SUCCESS);
                }
            }
            catch (Exception e)
            {
                return(e.Message);
            }
        }
示例#10
0
    private IEnumerator ParseLogin()
    {
        if (FB.IsLoggedIn)
        {
            // Logging in with Parse
            // print("______________________" + FB.UserId + " " + FB.AccessToken + " " + DateTime.Now);

            System.Threading.CancellationToken s = new System.Threading.CancellationToken();

            var aToken = Facebook.Unity.AccessToken.CurrentAccessToken;

            var loginTask = ParseFacebookUtils.LogInAsync(aToken.UserId,
                                                          aToken.TokenString,
                                                          DateTime.Now, s);
            while (!loginTask.IsCompleted)
            {
                yield return(null);
            }
            // Login completed, check results
            if (loginTask.IsFaulted || loginTask.IsCanceled)
            {
                // There was an error logging in to Parse
                foreach (var e in loginTask.Exception.InnerExceptions)
                {
                    ParseException parseException = (ParseException)e;
                    Debug.Log("ParseLogin: error message " + parseException.Message);
                    Debug.Log("ParseLogin: error code: " + parseException.Code);
                }
            }
            else
            {
                // Log in to Parse successful
                // Get user info
                FB.API("/me", HttpMethod.GET, FBAPICallback);
                // Display current profile info
                UpdateProfile();
            }
        }
    }
示例#11
0
    private void AuthCallback(ILoginResult result)
    {
        if (FB.IsLoggedIn)
        {
            var accessToken = Facebook.Unity.AccessToken.CurrentAccessToken;
            GlobalVariables.facebookLogin = true;

            Debug.Log("Facebook Acess token User ID: " + accessToken.UserId);
            Debug.Log("Permissions:");
            foreach (string perm in accessToken.Permissions)
            {
                Debug.Log(perm);
            }

            Task <ParseUser> logInTask = ParseFacebookUtils.LogInAsync(accessToken.UserId, accessToken.TokenString, accessToken.ExpirationTime);

            SceneManager.LoadScene(SceneBook.MAIN_MENU_NAME);
        }
        else
        {
            Debug.Log("Login cancelled.");
        }
    }
示例#12
0
    protected void HandleFBLoginResult(IResult result)
    {
        bool loggedInSuccessfully = false;

        if (result == null)
        {
            AddLog("Null Response from FB Login");
            loginPanel.setMode(LoginPanel.Mode.LOGGED_OUT);
            return;
        }

        // Some platforms return the empty string instead of null.
        if (!string.IsNullOrEmpty(result.Error))
        {
            AddLog("Error Response:\n" + result.Error);
        }
        else if (result.Cancelled)
        {
            AddLog("Cancelled Response:\n" + result.RawResult);
        }
        else if (!string.IsNullOrEmpty(result.RawResult))
        {
            AddLog("Success Response:\n" + result.RawResult);
            loggedInSuccessfully = true;

            AccessToken uat = AccessToken.CurrentAccessToken;
            AddLog("FB User Id: " + uat.UserId);

            GameObject loginPanelObject = loginPanel.gameObject;

            ParseFacebookUtils.LogInAsync(uat.UserId, uat.TokenString, uat.ExpirationTime).ContinueWith(t =>
            {
                // check for errors
                if (t.IsFaulted)
                {
                    Exception ex = t.Exception;
                    bufferedLog.Push(ex.ToString());
                }
                else if (t.IsCanceled)
                {
                    bufferedLog.Push("operation cancelled");
                }
                else
                {
                    bufferedLog.Push("[User " + ParseUser.CurrentUser.Username +
                                     " created] id = " + ParseUser.CurrentUser.ObjectId);

                    checkIfParseUserFbIdSaved(uat.UserId);
                }
                objectsToEnable.Push(loginPanelObject);
            });
        }
        else
        {
            AddLog("Empty Response\n");
        }

        // AddLog(result.ToString());

        if (!loggedInSuccessfully)
        {
            AddLog("FB Login unsuccessful, set panel to logged out");
            loginPanel.setMode(LoginPanel.Mode.LOGGED_OUT);
        }
    }
示例#13
0
        public async Task <UserModel> FacebookLogin()
        {
            var user = await ParseFacebookUtils.LogInAsync(new List <string>() { "email", "public_profile" });

            return(null);
        }
示例#14
0
    public void Start()
    {
        // update user parse task
        UpdateCommand.Subscribe(
            _ =>
        {
            ParseUser user = ParseUser.CurrentUser;

            String oldUsername = user.Username;
            String oldEmail    = user.Email;

            String newUsername = ProfileUsername.Value;
            String newPassword = ProfilePassword.Value;
            String newEmail    = ProfileEmail.Value;

            if (newUsername != "")
            {
                user.Username = newUsername;
            }
            if (newPassword != "")
            {
                user.Password = newPassword;
            }
            if (newEmail != "")
            {
                user.Email = newEmail;
            }

            AsyncSubject <Task> asyncSubject = new AsyncSubject <Task>();

            user.SaveAsync().ContinueWith(
                x =>
            {
                bool updateSuccessful = false;

                if (x.IsFaulted)
                {
                    LogParseError(x.Exception);
                    asyncSubject.OnError(x.Exception);
                }
                if (x.IsCompleted && !x.IsCanceled)
                {
                    if (!x.IsFaulted)
                    {
                        UserData.OnNext(ParseUser.CurrentUser);
                        updateSuccessful = true;
                    }

                    asyncSubject.OnNext(x);
                    asyncSubject.OnCompleted();
                }
                if (x.IsCanceled)
                {
                    asyncSubject.OnError(new OperationCanceledException());         // was TaskCanceledException(x))
                }

                if (!updateSuccessful)
                {
                    user.Username = oldUsername;
                    user.Email    = oldEmail;
                    asyncSubject.OnCompleted();
                }
            });

            return
            (UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
        });


        // login parse task
        LoginCommand.Subscribe(
            _ =>
        {
            var parseLoginStream = TaskObservableExtensions.ToObservable(
                ParseUser.LogInAsync(LoginUsername.Value, LoginPassword.Value));

            parseLoginStream.Subscribe(
                pu =>
            {
                UserData.OnNext(pu);
            },
                error =>
            {
                LogParseError(error);
            }
                );

            return
            (UniRx.Observable.AsUnitObservable(parseLoginStream).ObserveOnMainThread());
        });

        // logout task
        LogoutCommand.Subscribe(
            _ =>
        {
            AsyncSubject <Task> asyncSubject = new AsyncSubject <Task>();

            ParseUser.LogOutAsync().ContinueWith(
                x =>
            {
                if (x.IsFaulted)
                {
                    LogParseError(x.Exception);
                    asyncSubject.OnError(x.Exception);
                }
                if (x.IsCompleted && !x.IsCanceled)
                {
                    if (!x.IsFaulted)
                    {
                        UserData.OnNext(ParseUser.CurrentUser);
                    }

                    asyncSubject.OnNext(x);
                    asyncSubject.OnCompleted();
                }
                if (x.IsCanceled)
                {
                    asyncSubject.OnError(new OperationCanceledException());         // was TaskCanceledException(x))
                }
            });

            return(UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
        });

        // signup parse task
        SignupCommand.Subscribe(
            _ =>
        {
            ParseUser newUser = new ParseUser();

            newUser.Username = LoginUsername.Value;
            newUser.Password = LoginPassword.Value;

            AsyncSubject <Task> asyncSubject = new AsyncSubject <Task>();

            newUser.SignUpAsync().ContinueWith(
                x =>
            {
                if (x.IsFaulted)
                {
                    LogParseError(x.Exception);
                    asyncSubject.OnError(x.Exception);
                }
                if (x.IsCompleted && !x.IsCanceled)
                {
                    if (!x.IsFaulted)
                    {
                        UserData.OnNext(ParseUser.CurrentUser);
                    }

                    asyncSubject.OnNext(x);
                    asyncSubject.OnCompleted();
                }
                if (x.IsCanceled)
                {
                    asyncSubject.OnError(new OperationCanceledException());         // was TaskCanceledException(x))
                }
            });

            return(UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
        });

        // Facebook login task
        FBLoginCommand.Subscribe(
            _ =>
        {
            // we cascade this asyncSubject through 3 steps: fblogin, parseuserlogin, and parse fb id update
            AsyncSubject <FacebookDelegate <ILoginResult> > asyncSubject = new AsyncSubject <FacebookDelegate <ILoginResult> >();

            FacebookDelegate <ILoginResult> handleFBLoginResult =
                result =>
            {
                bool additionalOperation = false;

                if (result == null)
                {
                    Debug.Log("Null Response from FB Login");
                }
                // Some platforms return the empty string instead of null.
                if (!string.IsNullOrEmpty(result.Error))
                {
                    Debug.Log("Error Response:\n" + result.Error);
                }

                else if (result.Cancelled)
                {
                    Debug.Log("Cancelled Response:\n" + result.RawResult);
                }
                else if (!string.IsNullOrEmpty(result.RawResult))
                {
                    additionalOperation = true;
                    Debug.Log("Success Response:\n" + result.RawResult);

                    AccessToken uat = AccessToken.CurrentAccessToken;
                    Debug.Log("FB User Id: " + uat.UserId);

                    var parseLoginStream = TaskObservableExtensions.ToObservable(
                        ParseFacebookUtils.LogInAsync(uat.UserId, uat.TokenString, uat.ExpirationTime));

                    parseLoginStream.Subscribe(
                        pu =>
                    {
                        // if the user doesn't have an fbId field, we do another parse update call to add fbId field
                        if (!pu.ContainsKey(KEY_FBID))
                        {
                            Debug.Log("no fbId found: updating user");
                            pu["fbId"] = uat.UserId;
                            pu.SaveAsync().ContinueWith(t =>
                            {
                                if (t.IsFaulted)
                                {
                                    Exception ex = t.Exception;
                                    LogParseError(ex);
                                    asyncSubject.OnError(ex);
                                }
                                else if (t.IsCanceled)
                                {
                                    Debug.Log("user update cancelled");
                                }
                                else
                                {
                                    Debug.Log("[User " + pu.Username + " updated] id = " + pu.ObjectId);
                                    UserData.OnNext(pu);
                                }

                                asyncSubject.OnCompleted();
                            });
                        }
                        else
                        {
                            UserData.OnNext(pu);
                            asyncSubject.OnCompleted();
                        }
                    },
                        error =>
                    {
                        LogParseError(error);
                        asyncSubject.OnError(error);
                    }
                        );
                }
                else
                {
                    Debug.Log("Empty Response\n");
                }

                if (!additionalOperation)
                {
                    asyncSubject.OnCompleted();
                }
            };


            FB.LogInWithReadPermissions(new List <string>()
            {
                "public_profile", "email", "user_friends"
            }, handleFBLoginResult);

            return(UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
        });


        // facebook link
        FBLinkCommand.Subscribe(
            _ =>
        {
            ParseUser user = ParseUser.CurrentUser;

            // user is already linked to FB
            if (ParseFacebookUtils.IsLinked(user))
            {
                AsyncSubject <Task> asyncSubject = new AsyncSubject <Task>();

                ParseFacebookUtils.UnlinkAsync(user).ContinueWith(t =>
                {
                    // check for errors
                    if (t.IsFaulted)
                    {
                        LogParseError(t.Exception);
                        asyncSubject.OnError(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        Debug.Log("operation cancelled");
                    }
                    else
                    {
                        Debug.Log("[User " + user.Username + " FB unlinked]");
                        user.Remove("fbId");

                        // user unlinked, now update parse user
                        user.SaveAsync().ContinueWith(
                            x =>
                        {
                            if (x.IsFaulted)
                            {
                                LogParseError(x.Exception);
                                asyncSubject.OnError(x.Exception);
                            }
                            if (x.IsCompleted && !x.IsCanceled)
                            {
                                if (!x.IsFaulted)
                                {
                                    UserData.OnNext(ParseUser.CurrentUser);
                                }

                                asyncSubject.OnNext(x);
                                asyncSubject.OnCompleted();
                            }
                            if (x.IsCanceled)
                            {
                                asyncSubject.OnError(new OperationCanceledException());             // was TaskCanceledException(x))
                            }
                        });
                    }
                });

                return
                (UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
            }

            // user has not linked yet
            else
            {
                // we cascade this asyncSubject through 3 steps: fblogin, parseuserlink, and parse fb id update
                AsyncSubject <FacebookDelegate <ILoginResult> > asyncSubject = new AsyncSubject <FacebookDelegate <ILoginResult> >();

                FacebookDelegate <ILoginResult> handleFBLoginResult =
                    result =>
                {
                    bool additionalOperation = false;

                    if (result == null)
                    {
                        Debug.Log("Null Response from FB Login");
                    }
                    // Some platforms return the empty string instead of null.
                    if (!string.IsNullOrEmpty(result.Error))
                    {
                        Debug.Log("Error Response:\n" + result.Error);
                    }

                    else if (result.Cancelled)
                    {
                        Debug.Log("Cancelled Response:\n" + result.RawResult);
                    }
                    else if (!string.IsNullOrEmpty(result.RawResult))
                    {
                        additionalOperation = true;
                        Debug.Log("Success Response:\n" + result.RawResult);

                        AccessToken uat = AccessToken.CurrentAccessToken;
                        Debug.Log("FB User Id: " + uat.UserId);

                        ParseFacebookUtils.LinkAsync(user, uat.UserId, uat.TokenString, uat.ExpirationTime)
                        .ContinueWith(
                            t =>
                        {
                            if (t.IsFaulted)
                            {
                                Exception ex = t.Exception;
                                LogParseError(ex);
                                asyncSubject.OnError(ex);
                            }
                            else if (t.IsCanceled)
                            {
                                Debug.Log("user update cancelled");
                            }
                            else
                            {
                                // link success, now we add the fb field to user
                                user["fbId"] = uat.UserId;
                                user.SaveAsync().ContinueWith(
                                    t2 =>
                                {
                                    if (t2.IsFaulted)
                                    {
                                        Exception ex = t2.Exception;
                                        LogParseError(ex);
                                        asyncSubject.OnError(ex);
                                    }
                                    else if (t2.IsCanceled)
                                    {
                                        Debug.Log("user update cancelled");
                                    }
                                    else
                                    {
                                        Debug.Log("[User " + user.Username + " updated] id = " + user.ObjectId);
                                        UserData.OnNext(user);
                                    }

                                    asyncSubject.OnCompleted();
                                });
                            }
                        }
                            );
                    }
                    else
                    {
                        Debug.Log("Empty Response\n");
                    }

                    if (!additionalOperation)
                    {
                        asyncSubject.OnCompleted();
                    }
                };


                FB.LogInWithReadPermissions(new List <string>()
                {
                    "public_profile", "email", "user_friends"
                }, handleFBLoginResult);

                return
                (UniRx.Observable.AsUnitObservable(asyncSubject).ObserveOnMainThread());
            }
        });

        // check if user logged in
        UserData.OnNext(ParseUser.CurrentUser);
    }