title: Parse FB Login Crash on Function Not Included in Login
body: <p>I have integrated Parse Login (v1.10.3) and never had this issue  until I integrated FB Login (v4.8.2).  If uninstall and re-install the app and launch, when the app launches I receive an error from an activity that occurs after Login.  I have the MainActivity as the launch page and it checks for a current user.  If the current user is null it redirects to the LoginActivity.  The LoginActivity crashes with a Null Pointer Exception error that occurs in an Adapter linked to a Fragment called from the Main Adapter.  Why is my Login Activity being skipped? </p>
  
  <p>I have a lot of logs in my code as I was trying to determine if there is a current user value at some point or if there is any Login function executed that would cause it to skip the Login, but none of it is executed and the current user is always Null (which I expect). </p>
  
  <p><strong>Login Activity</strong></p>
  
  <pre><code>public static final List&lt;String&gt; mPermissions = new ArrayList&lt;String&gt;() {
      {
          add("public_profile");
          add("email");
          add("gender");
          add("user_birthday");
      }};
  
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_login);
  
      //set and transition to signup page
      mSignUpTextView = (TextView)findViewById(R.id.signupText);
      mSignUpTextView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
              startActivity(intent);
          }
      });
  
      //set and transition to reset password page
      mResetPasswordText = (TextView)findViewById(R.id.login_ForgotPasswordText);
      mResetPasswordText.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              Intent intent = new Intent(LoginActivity.this, ResetPasswordActivity.class);
              startActivity(intent);
          }
      });
  
      //set and handle all login tasks
      mUsername = (EditText)findViewById(R.id.usernameField);
      mPassword = (EditText)findViewById(R.id.passwordField);
      mLoginButton = (Button)findViewById(R.id.loginButton);
  
      //Facebook login
      loginButton = (LoginButton) findViewById(R.id.login_button);
      loginButton.setReadPermissions(Arrays.asList("public_profile, email, user_birthday, user_friends"));
  
      callbackManager = CallbackManager.Factory.create();
  
  
      mFbProfile = Profile.getCurrentProfile();
      Log.d("Login FB", String.valueOf(mFbProfile));
  
  
      // Other app specific specialization
  
      // Callback registration
      loginButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
  
              ParseFacebookUtils.logInWithReadPermissionsInBackground(LoginActivity.this, mPermissions, new LogInCallback() {
                  @Override
                  public void done(ParseUser user, ParseException err) {
  
                      if (user == null) {
                          Log.d("Login", "Uh oh. The user cancelled the Facebook login.");
                          if (err != null) {
                              Log.d("ParseFacebookLogin", "Error: " + err.getLocalizedMessage());
                          }
                      }
                      else if (user.isNew()) {
                          Log.d("Login", "User signed up and logged in through Facebook!");
                          getUserDetailsFromFB();
  
                          //success
                          FlokkApp.updateParseInstallation(user);
  
                          Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                          startActivity(intent);
  
                          Log.d("Login FB", "User logged in through Facebook!");
  
                      }
                      else {
                          Log.d("Login", "User logged in through Facebook!");
                          getUserDetailsFromParse();
  
                          //success
                          FlokkApp.updateParseInstallation(user);
  
                          Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                          startActivity(intent);
                      }
                  }
              });
  
          }
      });
  
  
  
  
  
      //Regular Parse Login ----------------------------------------------------------
      mLoginButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
  
              String username = mUsername.getText().toString();
              String password = mPassword.getText().toString();
  
              username = username.trim();
              password = password.trim();
  
              //noinspection StatementWithEmptyBody
              if (username.isEmpty() || password.isEmpty()){
                  // display message if field is blank
                  AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
                  builder.setMessage(R.string.login_error_message)
                          .setTitle(R.string.login_error_title)
                          .setPositiveButton(android.R.string.ok, null);
                  AlertDialog dialog = builder.create();
                  dialog.show();
              }
              else {
                  // login user
                  ParseUser.logInInBackground(username, password, new LogInCallback() {
                      public void done(ParseUser user, ParseException e) {
                          if (user != null) {
                              //success
                              FlokkApp.updateParseInstallation(user);
  
                              Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                              intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                              startActivity(intent);
                              //Toast.makeText(LoginActivity.this, "Successful Login", Toast.LENGTH_SHORT).show();
                          }
                          else {
                              AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
                              builder.setMessage(e.getMessage())
                                      .setTitle(R.string.login_error_title)
                                      .setPositiveButton(android.R.string.ok, null);
                              AlertDialog dialog = builder.create();
                              dialog.show();
                          }
                      }
                  });
              }
  
          }
      });
  }
  
  //Facebook login required below ------------------------------------
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      Log.d("Login", "on activity result");
  
      super.onActivityResult(requestCode, resultCode, data);
      ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
  }
  
  //Facebook save new user code -----------------------------------------------
  private void saveNewUser() {
      Log.d("Login", "Save new user");
  
  
      parseUser = ParseUser.getCurrentUser();
      parseUser.setUsername(name);
      parseUser.setEmail(email);
  
      //will need to update once I figure out how facebook sends the data
      boolean genderValue;
  
      if (gender == "Male") {
          genderValue = true;
      } else {
          genderValue = false;
      };
      parseUser.put(ParseConstants.KEY_GENDERMALE, genderValue);
  
      String searchtext = name.toLowerCase().trim();
      parseUser.put(ParseConstants.KEY_SEARCHTEXT, searchtext);
  
  
      //Saving profile photo as a ParseFile
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      Bitmap bitmap = null; //((BitmapDrawable) mProfileImage.getDrawable()).getBitmap();
  
      if (bitmap != null) {
          bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
          byte[] data = stream.toByteArray();
          String thumbName = parseUser.getUsername().replaceAll("\\s+", "");
          final ParseFile parseFile = new ParseFile(thumbName + "_android_FBLogin.jpg", data);
  
          parseFile.saveInBackground(new SaveCallback() {
              @Override
              public void done(ParseException e) {
                  parseUser.put(ParseConstants.KEY_PROFILEPIC, parseFile);
  
                  //Finally save all the user details
                  parseUser.saveInBackground(new SaveCallback() {
                      @Override
                      public void done(ParseException e) {
                          Toast.makeText(LoginActivity.this, "New user:" + name + " Signed up", Toast.LENGTH_SHORT).show();
                      }
                  });
  
              }
          });
      }
  
  }
  
  private void getUserDetailsFromFB() {
      Log.d("Login", "getUserDetails From FB");
  
      // Suggested by https://disqus.com/by/dominiquecanlas/
      Bundle parameters = new Bundle();
      parameters.putString("fields", "email,name,gender,picture");
  
  
      new GraphRequest(
              AccessToken.getCurrentAccessToken(),
              "/me",
              parameters,
              HttpMethod.GET,
              new GraphRequest.Callback() {
                  public void onCompleted(GraphResponse response) {
                      /* handle the result */
                      try {
  
                          Log.d("Response", response.getRawResponse());
  
                          email = response.getJSONObject().getString("email");
                          //mEmailID.setText(email);
  
                          name = response.getJSONObject().getString("name");
                          mUsername.setText(name);
  
                          gender = response.getJSONObject().getString("gender");
  
                          JSONObject picture = response.getJSONObject().getJSONObject("picture");
                          JSONObject data = picture.getJSONObject("data");
  
                          //  Returns a 50x50 profile picture
                          String pictureUrl = data.getString("url");
  
                          Log.d("Profile pic", "url: " + pictureUrl);
  
                          new ProfilePhotoAsync(pictureUrl).execute();
  
                      } catch (JSONException e) {
                          e.printStackTrace();
                      }
                  }
              }
      ).executeAsync();
  
  }
  
  private void getUserDetailsFromParse() {
      Log.d(" Login", "getUserDetails From parse");
  
      parseUser = ParseUser.getCurrentUser();
  
      //Fetch profile photo
      try {
          ParseFile parseFile = parseUser.getParseFile(ParseConstants.KEY_PROFILEPIC);
          byte[] data = parseFile.getData();
          Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
          //mProfileImage.setImageBitmap(bitmap);
  
      } catch (Exception e) {
          e.printStackTrace();
      }
  
      //mEmailID.setText(parseUser.getEmail());
      mUsername.setText(parseUser.getUsername());
  
      //Toast.makeText(LoginActivity.this, "Welcome back " + mUsername.getText().toString(), Toast.LENGTH_SHORT).show();
  
  }
  
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_login, menu);
      return true;
  }
  
      public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      int id = item.getItemId();
  
      //noinspection SimplifiableIfStatement
      if (id == R.id.action_settings) {
          return true;
      }
  
      return super.onOptionsItemSelected(item);
  }
  
  
  //Required for facebook
  class ProfilePhotoAsync extends AsyncTask&lt;String, String, String&gt; {
      public Bitmap bitmap;
      String url;
  
      public ProfilePhotoAsync(String url) {
          this.url = url;
      }
  
      @Override
      protected String doInBackground(String... params) {
          // Fetching data from URI and storing in bitmap
          bitmap = DownloadImageBitmap(url);
          return null;
      }
  
      @Override
      protected void onPostExecute(String s) {
          super.onPostExecute(s);
          //mProfileImage.setImageBitmap(bitmap);
  
          saveNewUser();
      }
  }
  
  public static Bitmap DownloadImageBitmap(String url) {
      Bitmap bm = null;
      try {
          URL aURL = new URL(url);
          URLConnection conn = aURL.openConnection();
          conn.connect();
          InputStream is = conn.getInputStream();
          BufferedInputStream bis = new BufferedInputStream(is);
          bm = BitmapFactory.decodeStream(bis);
          bis.close();
          is.close();
      } catch (IOException e) {
          Log.e("IMAGE", "Error getting bitmap", e);
      }
      return bm;
  }
  </code></pre>
  
  <p><strong>Main Activity</strong></p>
  
  <pre><code>@Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      ParseAnalytics.trackAppOpened(getIntent());
  
      ParseUser currentUser = ParseUser.getCurrentUser();
      if (currentUser == null) {
          navigateToLogin();
          Log.d("Login Check", String.valueOf(ParseUser.getCurrentUser()));
  
      }
      else {
      }
  
      toolbar = (Toolbar) findViewById(R.id.app_bar);
      setSupportActionBar(toolbar);
  
      mPager = (ViewPager) findViewById(R.id.pager);
      mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
      mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
      mTabs.setDistributeEvenly(true);
      mTabs.setViewPager(mPager);
  
  
  
      try {
          PackageInfo info = getPackageManager().getPackageInfo(
                  "com.myflokk.testflokkd",
                  PackageManager.GET_SIGNATURES);
          for (Signature signature : info.signatures) {
              MessageDigest md = MessageDigest.getInstance("SHA");
              md.update(signature.toByteArray());
              Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
          }
      } catch (PackageManager.NameNotFoundException e) {
  
      } catch (NoSuchAlgorithmException e) {
  
      }
  
  
  }
  
  //included onResume as a part of facebook integration
  @Override
  protected void onResume() {
      super.onResume();
  
      // Logs 'install' and 'app activate' App Events.
      AppEventsLogger.activateApp(this);
  }
  
  //included onPause as a part of facebook integration
  @Override
  protected void onPause() {
      super.onPause();
  
      // Logs 'app deactivate' App Event.
      AppEventsLogger.deactivateApp(this);
  }
  
  
  
  private void navigateToLogin() {
      Intent intent = new Intent(MainActivity.this, LoginActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
      startActivity(intent);
  }
  
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return true;
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will automatically handle clicks on the Home/Up button, so long as you specify a parent activity in AndroidManifest.xml.
      int id = item.getItemId();
  
      //noinspection SimplifiableIfStatement
  
      switch (id) {
  
          case R.id.addEvent:
              startActivity(new Intent(this, AddEventActivity.class));
              break;
  
          case R.id.editProfile:
              startActivity(new Intent(this, UserProfileEditActivity.class));
              break;
  
          case R.id.action_logout:
              ParseUser.logOut();
              navigateToLogin();
              break;
  
  
      }
      return super.onOptionsItemSelected(item);
  }
  
  @Override
  public void onStart() {
      super.onStart();
  
      ParseUser currentUser = ParseUser.getCurrentUser();
      if (currentUser == null) {
          navigateToLogin();
          Log.d("Login Check 2", String.valueOf(ParseUser.getCurrentUser()));
  
      }
      else {
      }
  
      // ATTENTION: This was auto-generated to implement the App Indexing API.
      // See https://g.co/AppIndexing/AndroidStudio for more information.
      client.connect();
      Action viewAction = Action.newAction(
              Action.TYPE_VIEW, // TODO: choose an action type.
              "Main Page", // TODO: Define a title for the content shown.
              // TODO: If you have web page content that matches this app activity's content,
              // make sure this auto-generated web page URL is correct.
              // Otherwise, set the URL to null.
              Uri.parse("http://host/path"),
              // TODO: Make sure this auto-generated app deep link URI is correct.
              Uri.parse("android-app://com.myflokk.testflokkd/http/host/path")
      );
      AppIndex.AppIndexApi.start(client, viewAction);
  }
  
  @Override
  public void onStop() {
      super.onStop();
  
      // ATTENTION: This was auto-generated to implement the App Indexing API.
      // See https://g.co/AppIndexing/AndroidStudio for more information.
      Action viewAction = Action.newAction(
              Action.TYPE_VIEW, // TODO: choose an action type.
              "Main Page", // TODO: Define a title for the content shown.
              // TODO: If you have web page content that matches this app activity's content,
              // make sure this auto-generated web page URL is correct.
              // Otherwise, set the URL to null.
              Uri.parse("http://host/path"),
              // TODO: Make sure this auto-generated app deep link URI is correct.
              Uri.parse("android-app://com.myflokk.testflokkd/http/host/path")
      );
      AppIndex.AppIndexApi.end(client, viewAction);
      client.disconnect();
  }
  
  
  class MyPagerAdapter extends FragmentPagerAdapter {
      String[] tabs;
  
      public MyPagerAdapter(FragmentManager fm) {
          super(fm);
          tabs = getResources().getStringArray(R.array.tabs);
      }
  
      @Override
      public Fragment getItem(int position) {
  
          switch (position) {
              case 0:
                  return new UserEventListFragment();
              case 1:
                  return new UserSearchFragment();
              case 2:
                  return new UserProfileActivityFragment();
          }
          return null;
      }
  
      @Override
      public CharSequence getPageTitle(int position) {
          return tabs[position];
      }
  
      @Override
      public int getCount() {
          return 3;
      }
  }
  </code></pre>
  
  <p><strong>Event Adapter that Causes the Error</strong></p>
  
  <pre><code>protected Context mContext;
  protected List&lt;ParseObject&gt; mEvents;
  private SimpleDateFormat mFormat = new SimpleDateFormat("E, MMM d", Locale.US);
  protected Date mDate;
  protected List&lt;Object&gt; mLikeList = new ArrayList&lt;&gt;();
  protected int mLikes = 0;
  protected String Flokking = "I am flokking to this event!";
  
  public EventAdapter(Context context, List&lt;ParseObject&gt; events) {
      super(context, R.layout.row_event_list, events);
      mContext = context;
      mEvents = events;
  }
  
  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
      final ViewHolder holder;
  
      if (convertView == null) {
  
          convertView = LayoutInflater.from(mContext).inflate(R.layout.row_event_list, null);
          holder = new ViewHolder();
          holder.eventName = (TextView) convertView.findViewById(R.id.eventRow_TextEventName);
          holder.eventLocation = (TextView) convertView.findViewById(R.id.eventRow_TextEventLocation);
          holder.eventImage = (ImageView) convertView.findViewById(R.id.eventRow_EventImage);
          holder.eventDate = (TextView) convertView.findViewById(R.id.eventRow_Date);
          holder.eventNotLiked = (ImageView) convertView.findViewById(R.id.eventRow_ImageNotLiked);
          holder.eventLiked = (ImageView) convertView.findViewById(R.id.eventRow_ImageLiked);
          holder.eventFlokkingCount = (TextView) convertView.findViewById(R.id.eventRow_FlokkingCount);
  
          convertView.setTag(holder);
      } else {
          holder = (ViewHolder) convertView.getTag();
      }
  
  
      ParseObject event = mEvents.get(position);
      ParseObject details = mEvents.get(position);
      final String currentEvent = details.getObjectId();
  
      //Log.d("EventAdapter", "This is the position --&gt; " + position);
  
      holder.eventName.setText(event.getString(ParseConstants.KEY_EVENTNAME));
      holder.eventLocation.setText(event.getString(ParseConstants.KEY_EVENTVENUE));
      holder.eventFlokkingCount.setText(event.getNumber(ParseConstants.EVENT_LIKECOUNT).toString());
  
      //get the date and assign to mDate and then change the way the date is displayed
      mDate = event.getDate(ParseConstants.KEY_EVENTDATE);
      holder.eventDate.setText(mFormat.format(mDate));
  
  
      mLikeList = event.getList(ParseConstants.EVENT_LIKES);
      Log.d("Login Event Check", String.valueOf(ParseUser.getCurrentUser()));
  
      if (mLikeList == null || mLikeList.isEmpty()) {
          //this is false and the user has not liked the event
          holder.eventLiked.setVisibility(View.INVISIBLE);
          holder.eventNotLiked.setVisibility(View.VISIBLE);
      }
  
      else {
          //if there are users in the list check for the current user
  
          if (mLikeList.contains(ParseUser.getCurrentUser().getObjectId())) {
              // true
              holder.eventLiked.setVisibility(View.VISIBLE);
              holder.eventNotLiked.setVisibility(View.INVISIBLE);
          }
          else {
              holder.eventLiked.setVisibility(View.INVISIBLE);
              holder.eventNotLiked.setVisibility(View.VISIBLE);
          }
      }
  </code></pre>
  
  <p><strong>Error Log</strong></p>
  
  <pre><code>02-01 19:05:28.800 E/AndroidRuntime: FATAL EXCEPTION: main
                                       Process: com.myflokk.testflokkd, PID: 1933
                                       java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.parse.ParseUser.getObjectId()' on a null object reference
                                           at com.myflokk.testflokkd.Adapters.EventAdapter.getView(EventAdapter.java:98)
  </code></pre>