uber requestRide() method Response Error 401: Unau

2019-08-18 16:16发布

问题:

I am getting Error when I try to call requestRide() method on Uber api. The response body is null and the response message is "Unauthorized" with error code 401; whereas the onResponse() callback method is executing but onFailure() callback method is not executing.

Here is my code for calling requestRide() and implementing the callback interface...

private void requestForNewRide(RidesService service, int position){
        RideRequestParameters rideRequestParameters = new RideRequestParameters.Builder().setPickupCoordinates(PICKUP_LATITUDE, PICKUP_LONGITUDE)
                .setProductId(productIds.get(position))
                .setFareId(fareIds.get(position))
                .setDropoffCoordinates(DROPOFF_LATITUDE, DROPOFF_LONGITUDE)
                .build();
        service.requestRide(rideRequestParameters).enqueue(new Callback<Ride>() {
            @Override
            public void onResponse(Call<Ride> call, Response<Ride> response) {

                if (response.isSuccessful()) {
                    Toast.makeText(CustomActivity.this, "Request ride success", Toast.LENGTH_SHORT).show();

                    try {
                        //ride details
                        String rideId = response.body().getRideId();
                        String rideStatus = response.body().getStatus();
                        Integer rideEta = response.body().getEta();                           //estimated time of arrival in min
                        Float rideSurgeMultiplier = response.body().getSurgeMultiplier();     //rise in price
                        Driver rideDriver = response.body().getDriver();
                        Location rideLocation = response.body().getLocation();
                        Vehicle rideVehicle = response.body().getVehicle();

                        //ride driver details
                        String driverName = rideDriver.getName();
                        String driverPhoneNumber = rideDriver.getPhoneNumber();
                        String driverPictureUri = rideDriver.getPictureUrl();
                        Float driverRating = rideDriver.getRating();

                        //ride Location details
                        Float rideLocationLatitude = rideLocation.getLatitude();
                        Float rideLocationLongitude = rideLocation.getLongitude();
                        Integer rideLocationBearing = rideLocation.getBearing();

                        //ride Vehicle details
                        String rideVehicleLicencePlate = rideVehicle.getLicensePlate();
                        String rideVehicleMake = rideVehicle.getMake();
                        String rideVehicleModel = rideVehicle.getModel();
                        String rideVehiclePictureUrl = rideVehicle.getPictureUrl();

                        //Log
                        Log.d("uberridedetails", "rideId: " + rideId);
                        Log.d("uberridedetails", "rideStatus: " + rideStatus);
                        Log.d("uberridedetails", "rideEta: " + rideEta);
                        Log.d("uberridedetails", "rideSurgeMultiplier: " + rideSurgeMultiplier);
                        Log.d("uberridedetails", "driverName: " + driverName);
                        Log.d("uberridedetails", "driverPhoneNumber: " + driverPhoneNumber);
                        Log.d("uberridedetails", "driverPictureUri: " + driverPictureUri);
                        Log.d("uberridedetails", "driverRating: " + driverRating);
                        Log.d("uberridedetails", "rideLocationLatitude: " + rideLocationLatitude);
                        Log.d("uberridedetails", "rideLocationLongitude: " + rideLocationLongitude);
                        Log.d("uberridedetails", "rideLocationBearing: " + rideLocationBearing);
                        Log.d("uberridedetails", "rideVehicleLicencePlate: " + rideVehicleLicencePlate);
                        Log.d("uberridedetails", "rideVehicleMake: " + rideVehicleMake);
                        Log.d("uberridedetails", "rideVehicleModel: " + rideVehicleModel);
                        Log.d("uberridedetails", "rideVehiclePictureUrl: " + rideVehiclePictureUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else {
                    Toast.makeText(CustomActivity.this, "Error: "+response.message(), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<Ride> call, Throwable t) {
                Toast.makeText(CustomActivity.this, "Failed to request ride", Toast.LENGTH_SHORT).show();
            }
        });
    }

I have already checked the param productId and FareId is valid, which I am getting from the api itself (by calling estimateRide() I get Price object from that I have got the fareId. And by calling getProducts() on RideService object I have got the productId.

This is the code for set up...

 SessionConfiguration config = new SessionConfiguration.Builder()
                .setClientId(getResources().getString(R.string.client_id))
                .setRedirectUri(getResources().getString(R.string.redirect_url))
                .setEnvironment(SessionConfiguration.Environment.SANDBOX)
                .setScopes(Arrays.asList(Scope.PROFILE, Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.REQUEST_RECEIPT))
                .build();
        UberSdk.initialize(config);

And ...

LoginCallback loginCallback = new LoginCallback() {
            @Override
            public void onLoginCancel() {
                // User canceled login
                Toast.makeText(CustomActivity.this, "User canceled login", Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onLoginError(@NonNull AuthenticationError error) {
                // Error occurred during login
                Toast.makeText(CustomActivity.this, "Error occurred during login", Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onLoginSuccess(@NonNull AccessToken accessToken) {
                // Successful login!  The AccessToken will have already been saved.
                Toast.makeText(CustomActivity.this, "Successful login!  The AccessToken will have already been saved.", Toast.LENGTH_SHORT).show();
                createSession();
            }
            @Override
            public void onAuthorizationCodeReceived(@NonNull String authorizationCode) {
                Toast.makeText(CustomActivity.this, "Authorization code received", Toast.LENGTH_SHORT).show();
                createSession();
            }
        };
        AccessTokenManager accessTokenManager = new AccessTokenManager(getApplicationContext());
        LoginManager loginManager = new LoginManager(accessTokenManager, loginCallback);
        loginManager.setRedirectForAuthorizationCode(true);
        loginManager.login(this);
        mAccessTokenManager = accessTokenManager;
        mLoginManager = loginManager;

Note1: These are the scopes I am using...

Scope.PROFILE, Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.REQUEST_RECEIPT

Note2: I am logging in with my developer account.

Let me know if I should mention any other details.

回答1:

Absolutely I have found out the solution on my own.

I noticed that the onLoginSuccess() callback method is being called only when I am using GENERAL SCOPEs.

Whenever I am using a RESTRICTED SCOPE, the method is not being called, instead another callback method named onAuthorizationCodeReceived() is being called.

Then I have found out, whenever the onAuthorizationCodeReceived() method is called, there is no access token saved in the AccessTokenManager object. Thus without the access token, when I try to request a ride Error returns "Unauthorized".

So, I tried to figure out how to generate Access token using the authorization code. I found no doc regarding this process in the Android section. Then I have found out the solution in the REST web service api.

Here is the LINK of my answer...

NOTE: There is no mention of the callback method onAuthorizationCodeReceived() in the Uber Doc.