Giter Site home page Giter Site logo

loopback-sdk-android's People

Contributors

amir-61 avatar b-admike avatar bajtos avatar cgole avatar crandmck avatar dhmlau avatar gmxtian avatar gunjpan avatar loay avatar mekuanent avatar pukoren avatar raymondfeng avatar rmg avatar siddhipai avatar slnode avatar sltest avatar superkhau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopback-sdk-android's Issues

Publish a new version to Maven Central under the new name

  • The latest version in Maven Central is 1.2.0, while the latest git tag is 1.3.0.
  • The project name has changed to loopback-sdk-android in the meantime.
  • API docs shows version 1.4.1 in the menu and 1.3.1-SNAPSHOT in the content.

A new version release will fix all three issues in one go.

Once the new version is released, we need to update the Confluence documentation too (link).

Tasks

500 Internal Server Error on save

Hello , I get 500 Internal Server Error when trying to save an entity. I'm using the mongodb connector.
What can be the cause?
Entity :

 {
  "name": "Libro",
  "plural": "libros",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "title": {
      "type": "string",
      "required": true
    },
    "category": {
      "type": "string",
      "required": true
    },
    "description": {
      "type": "string"
    },
    "location": {
      "type": "string"
    },
    "datePub": {
      "type": "date",
      "required": true
    }
  },
  "validations": [],
  "relations": {
    "people": {
      "type": "hasAndBelongsToMany",
      "model": "Person",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": {}
}

Android code:

RestAdapter adapter = new RestAdapter(getActivity().getApplicationContext(), "http://192.168.1.15:3000/api");

LibroRepository libroRepository = adapter.createRepository(LibroRepository.class);

Libro libro = libroRepository.createObject(ImmutableMap.of("name", "Libro"));
p.setTitle(((EditText) rootView.findViewById(R.id.etTitle)).getText().toString());
p.setCategory(((EditText) rootView.findViewById(R.id.etCategory)).getText().toString());
p.setDescription(((EditText) rootView.findViewById(R.id.etDescription)).getText().toString());
p.setLocation(((EditText) rootView.findViewById(R.id.etLocation)).getText().toString());
DatePicker dp = (DatePicker) rootView.findViewById(R.id.dpDatePub);
Calendar cal = Calendar.getInstance();
cal.set(dp.getYear(), dp.getMonth(), dp.getDayOfMonth());
p.setDatePub(cal.getTime());

                p.save(new VoidCallback() {
                    @Override
                    public void onSuccess() {
                        String ok = "ok";
                    }

                    @Override
                    public void onError(Throwable t) {
                        String err = t.getMessage();
                    }
                });

Model:

public class Libro extends Model{
    private String title;
    private String category;
    private String description;
    private String location;
    private Date datePub;

// Getters and Setters...
}

Thanks in advance!

How send a complex object via the API ?

How can I implement saving a complex object from Android to the Server.
The object is defined as object type on the server, and on Android is a Hashmap of subObjects, which are itself hashmaps.

Support Nested Models

I'm trying to define a model with an array of models inside it with the Android SDK and I'm struggling with a casting problem from HashMap to my model.
Let's take for example a model called Feed that contains an array of Posts (which is a model also) and a link to the next page (a simple string).
When I try to get a Feed object with a custom static method using the JsonObjectParser, it throws an exception that it can't cast HashMap to Post.
Right now, the only solution I came up with is to overload the setter of Posts with ArrayList<HasMap<String, ? extends Object>> as a parameter instead of ArrayList<Post>.

loginUser problem java.lang.NoSuchMethodError: No virtual method post

I have created a model based on User.
In my java code I have created these classes:
Utenti.java

package com.marcoferraioli.gate42.passmuesum.loopback;

public class Utenti extends com.strongloop.android.loopback.User {
}

UtentiRepository.java

package com.marcoferraioli.gate42.passmuesum.loopback;

public class UtentiRepository extends com.strongloop.android.loopback.UserRepository<Utenti> {

    public interface LoginCallback extends com.strongloop.android.loopback.UserRepository.LoginCallback<Utenti> {

    }

    public UtentiRepository() {
        super("utenti", null, Utenti.class);
    }
}

this is part of code of the activity where I make to login

......
......
final RestAdapter adapter = new RestAdapter(getApplicationContext(), "http://xxxxxx.marcoferraioli.com:3000/api");
final UtentiRepository utentiRepo = adapter.createRepository(UtentiRepository.class);
......
......
utentiRepo.loginUser(username, password, new UtentiRepository.LoginCallback() {
                        @Override
                        public void onSuccess(AccessToken token, Utenti currentUser) {
                            Log.d("Success", token.getUserId() + ":" + currentUser.getId());
                            Intent myIntent = new Intent(getApplicationContext(), NextActivity.class);
                            startActivity(myIntent);
                            finish();
                        }

                        @Override
                        public void onError(Throwable t) {
                            Log.e("Chatome", "Login E", t);
                        }
                    });
......
......

But where i try to login I receive this error:

09-15 17:18:48.316 13166-13166/com.marcoferraioli.gate42.passmuesum E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.marcoferraioli.gate42.passmuesum, PID: 13166
java.lang.NoSuchMethodError: No virtual method post(Landroid/content/Context;Ljava/lang/String;[Lorg/apache/http/Header;Lorg/apache/http/HttpEntity;Ljava/lang/String;Lcom/loopj/android/http/ResponseHandlerInterface;)Lcom/loopj/android/http/RequestHandle; in class Lcom/strongloop/android/remoting/adapters/RestAdapter$RestHttpClient; or its super classes (declaration of 'com.strongloop.android.remoting.adapters.RestAdapter$RestHttpClient' appears in /data/data/com.marcoferraioli.gate42.passmuesum/files/instant-run/dex/slice-loopback-sdk-android-1.5.2_37a7b873dd8c3edb1e8ff47bba0449144d758c3a-classes.dex)
at com.strongloop.android.remoting.adapters.RestAdapter$RestHttpClient.request(RestAdapter.java:473)
at com.strongloop.android.remoting.adapters.RestAdapter.request(RestAdapter.java:204)
at com.strongloop.android.remoting.adapters.RestAdapter.invokeStaticMethod(RestAdapter.java:136)
at com.strongloop.android.remoting.adapters.RestAdapter.invokeStaticMethod(RestAdapter.java:109)
at com.strongloop.android.remoting.Repository.invokeStaticMethod(Repository.java:115)
at com.strongloop.android.loopback.UserRepository.loginUser(UserRepository.java:231)
at com.marcoferraioli.gate42.passmuesum.LoginActivity$2.onClick(LoginActivity.java:118)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5253)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Sorry for my bad English

User.save(email, password) returns successful even when no email was successfully sent

User.save(email, password) is standard model save so there is no check if email was sent out by nodemailer. I'm always getting ok no matter what. How to check that nodemailer sent off the registration email? Also how to regenerate the email later if email could not go through? User is now saved and it will treat as duplicate. Most registrations have resend confirmation, how can this be done with sdk?

how to cancel request from RestAdapter?

Hi, i want to create auto suggest to my loopback service, the behaviour is every afterTextChanged the request fired, but if onTextChanged, i want to cancel the request, i know in loopj it will use cancelRequest() to do so but i don't have idea how to cancel request from RestAdapter?

any clue will be helpful, thanks!

null pointer from using RestAdapter

I got this when I start using the RestAdapter at oncreate in the activity.

07-22 17:10:27.423 14026-14026/tileview.demo E/AndroidRuntime: FATAL EXCEPTION: main
Process: tileview.demo, PID: 14026
java.lang.RuntimeException: Unable to start activity ComponentInfo{****}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.loopj.android.http.AsyncHttpClient.addHeader(java.lang.String, java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.loopj.android.http.AsyncHttpClient.addHeader(java.lang.String, java.lang.String)' on a null object reference
at com.strongloop.android.loopback.RestAdapter.setAccessToken(RestAdapter.java:32)
at com.strongloop.android.loopback.RestAdapter.(RestAdapter.java:27)
at com.galleria.loopbackdataclip.GalleriaLB.init(GalleriaLB.java:101)
at com.galleria.loopbackdataclip.GalleriaLB.getInstance(GalleriaLB.java:57)
at tileview.demo.NetworkMap.onCreate(NetworkMap.java:38)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5422) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Describe how to invoke a custom method, include an example

It will be nice to have a more explaination of "how to invoke a custom method from Android". Explaining what is happening on each line for better understanding.

Also, it will be really helpful if runnable runtrip example is added with other examples.

NOTE: By round trip i mean "Android---> Loopback --->Android" trip.

The history of creating this issue can be found here -

http://stackoverflow.com/questions/27087760/loopback-custom-method-call-from-android/27126976?noredirect=1#comment42785947_27126976

can't get current user id from MainActivity

I am using loopback-sdk-android for my app, I login the user successfully, and I can access the token and the user object in the LoginActivity. But when i try to get the current user id from the following activities (MainActivity or other) it always returns null!
Official documentation says the SDK is supposed to automatically save these in SharedPreferences, put how can I access them from other activities?

How to check if an installation exists

From https://groups.google.com/forum/#!topic/loopbackjs/Rz4kyjp_rq0/discussion.

Looking at the LocalInstallation class in the loopback-android repo, there is a save method but not really any others that interface with the loopback API AFAIK. I'm interested in a check exists method (/api/installations/{id}/exists). In particular, I'd like to have it so I can keep track of users who download an android app but haven't yet created an account.. That is, save installations before they can be associated with a userId (setting userId to -1 or something like that). To know whether or not to update the installation on the front screen (pre-login), setting the userId to -1, I need to know whether or not the installation exists already to avoid overwriting a user id that could still be associated with a user that is logged out or "Inactive".

  • Is writing a method in that class what you'd recommend?
  • If so, would the code look something like this?
    public void checkExists(final ObjectCallback callback) {
        ModelRepository<Model> repository =
                loopbackAdapter.createRepository("installation");
        final Model model = repository.createModel(
                BeanUtil.getProperties(this, false, false));      // I'm assuming this takes care of SharedPreferences id stuff..

        model.checkExists(new ObjectCallback() {      // checkExists would have to be written in Model.java
            @Override
            public void onSuccess() {
                result = model.exists();            // exists method would have to be written too.. 
                callback.onSuccess(boolean result);
            }

            @Override
            public void onError(Throwable t) {
                if (t instanceof HttpResponseException) {
                     // something graceful here.. 
                }
                callback.onError(t);
            }
        });
    }

If this is the way to go about it, happy to give it a shot. Wanted to check first before I dive in tho. Also wouldn't be very hard to write some Android code that just checks the server with a background task, however figured I'd try to use the loopback android library as much as possible to minimize code..

From Miroslav
The current implementation of LocalInstallation class should already support your use case, at least in my opinion:

  • at startup, create a new LocalInstallation instance, fill all properties except userId and call save()
  • after login, create a new LocalInstallation instance, fill all properties including userId and call save()
  • after logout, create a new LocalInstallation instance, fill all properties, set userId to null, and call save()

LocalInstance is storing the installationId in SharedPreferences, thus the save() method is always updating the same server instance of Installation model.

To know whether or not to update the installation on the front screen (pre-login), setting the userId to -1, I need to know whether or not the installation exists already to avoid overwriting a user id that could still be associated with a user that is logged out or "Inactive".

Every Installation instance is assigned a unique id bound the the copy of the application on a single device. No two devices share the same installation ids.

I don't understand why the "exists" check is needed to prevent overriding user ids. Could you please explain this in more detail? It's possible I am missing something here.

Perhaps what is needed is a better integration of LocalInstallation with authorization, so that LocalInstallation automatically fills the id of the user which is currently authenticated with the app? This should be IMO done on the server - when a local installation is create or updated, the userId should be overriden with the value from the access token.

Great call. By using null for userId at startup (not setting it at all, instead of setting to -1), eliminates need for exists call. Better solution, thanks.

Just to recap for anyone in future. Made two minor tweaks, but these steps are a solid way to do it as you suggested:

  • at startup, create a new LocalInstallation instance, fill all properties except userId and call save()
  • after login, create a new LocalInstallation instance, fill all properties including userId and call save()
  • after logout, create a new LocalInstallation instance, fill all properties, set userId to null, and call save() NOTE: I don't set userId back to null here.. Just set installation to inactive. Figure it will be nice to know the last user who was logged in on a device. Likely will not use ever, but just in case I wanted to figure out demographics for people who logged out might be useful. Can still associate logged out devices with the last user logged in this way.

By doing it this way it covers every case I can think of:

  • first startup -> installation created with userid null, device token and object id created, status inactive
  • login -> installation updated by setting userid and status to active (I actually make this call from our main non-loopback server that does login, figure more reliable network connection)
  • logout -> installation updated to inactive (userId not changed, not overwriting last user logged in on a specific device to null)

There was one edge case where I had to add extra call: already logged in on new device (broken/lost phone recovery sort of thing, where old shared preferences make it to new device) -> update device token

Add to Model class another save method to return the response of the object being added

The way currently the save in Model is implemented is:

public void save(final VoidCallback callback) {
        invokeMethod(id == null ? "create" : "save", toMap(),
                new Adapter.JsonObjectCallback() {

            @Override
            public void onError(Throwable t) {
                callback.onError(t);
            }

            @Override
            public void onSuccess(JSONObject response) {
                Object id = response.opt("id");
                if (id != null) {
                    setId(id);
                }
                callback.onSuccess();
            }
        });
    }

Sometimes after saving something to the database you care about getting the JsonResponseObject, like maybe getting the ID for the object saved from the ResponseObject. So I was thinking that we have another save method in the Model class that actually returns a JSONResponseObject like this

public void save(final JsonObjectCallback callback) {
        invokeMethod(id == null ? "create" : "save", toMap(),
                new Adapter.JsonObjectCallback() {

            @Override
            public void onError(Throwable t) {
                callback.onError(t);
            }

            @Override
            public void onSuccess(JSONObject response) {
                Object id = response.opt("id");
                if (id != null) {
                    setId(id);
                }
                callback.onSuccess(response);
            }
        });
    }

Android minimum SDK version: 8 or 14 ?

Hello,

In the AndroidManifest.xml, minimum SDK version is specified to be 8:
https://github.com/strongloop/loopback-sdk-android/blob/master/src/main/AndroidManifest.xml

But in the build.gradle file, minSdkVersion is set to 14:
https://github.com/strongloop/loopback-sdk-android/blob/master/build.gradle

Our project needs to be API 8 compatible to target a large number of devices but when including the dependency the gradle compilation fails (because of API 14).

We are currently using http-async and it works with API 8, guava seems to be compatible with API 8 too. I cloned the repo and changed minSdkVersion to 8 in the build.gradle file and everything compiled well.
Do you plan to make it usable with API 8 soon ?

Cheers,
Jonathan

[What about support for Android Marshmallow - API 23]

Hi All,
I just want to check whether is there any plan to update this library to support Android APIs of 23 version.
As org.apache.http libraries have been deprecated and support is removed in Marshmallow. Also android-async-http does not use apache http client instead it uses different library cz.msebera.android:httpclient. Please refer to this change in following link:
android-async-http/android-async-http@15f9556#diff-0d1d9100a9b6813b8cb5c470bf313d00

I am trying to upgrade both loopback and asynchttp libs and facing a number of issues because both now are using different sets of httpclient libraries.

Kindly share if there are plans to change it.

Thanks...

Returning 0 or null values for some properties

I have a project on GitHub I am building for my Master's degree project. I am new to Android, but have been working with Loopback for nearly a year now, on various other work and personal projects,

There is a strange little bug I can't seem to figure out.
One model is receiving null for two String properties and a zero for an "int" property.
Another model is receiving a zero for an "int" property.

This happens regardless of the value in the database for those properties. All the other properties do not have the issue.

The properties returning null or zero
https://github.com/alexxgathp/vap/blob/master/client/android-vap-demo/app/src/main/java/com/alexxg/android_vap_demo/DemoTwo.java#L95

https://github.com/alexxgathp/vap/blob/master/client/android-vap-demo/app/src/main/java/com/alexxg/android_vap_demo/DemoTwo.java#L96

https://github.com/alexxgathp/vap/blob/master/client/android-vap-demo/app/src/main/java/com/alexxg/android_vap_demo/DemoTwo.java#L99

https://github.com/alexxgathp/vap/blob/master/client/android-vap-demo/app/src/main/java/com/alexxg/android_vap_demo/DemoTwo.java#L55
The model definitions
https://github.com/alexxgathp/vap/blob/master/common/models/device.json
https://github.com/alexxgathp/vap/blob/master/common/models/video.json
The issue
GrandmasterGrogu/vap#3
My repository
https://github.com/alexxgathp/vap

Fix failing unit-tests

The unit-tests in the current master HEAD are failing. They were still passing in 353014c. I suspect the problem is caused by @raymondfeng changes made on July 01-02 and/or changes made in loopback-component-storage.

Getting java.lang.NoSuchMethodError exception when calling findAll

I have been getting the following error when I call the method:

RestAdapter(context, "url-here").createRepository("blah").findAll
java.lang.NoSuchMethodError: com.strongloop.android.remoting.adapters.RestAdapter$RestHttpClient.get
                                                                              at com.strongloop.android.remoting.adapters.RestAdapter$RestHttpClient.request(RestAdapter.java:473)
                                                                              at com.strongloop.android.remoting.adapters.RestAdapter.request(RestAdapter.java:202)
                                                                              at com.strongloop.android.remoting.adapters.RestAdapter.invokeStaticMethod(RestAdapter.java:134)
                                                                              at com.strongloop.android.remoting.adapters.RestAdapter.invokeStaticMethod(RestAdapter.java:107)
                                                                              at com.strongloop.android.remoting.Repository.invokeStaticMethod(Repository.java:115)
                                                                              at com.strongloop.android.loopback.ModelRepository.find(ModelRepository.java:160)
                                                                              at com.strongloop.android.loopback.ModelRepository.findAll(ModelRepository.java:150)
...

In my build.gradle file, I have:

compile 'com.strongloop:loopback-sdk-android:1.6.0'
compile 'com.loopj.android:android-async-http:1.4.9'

Oddly enough, this has only started happening for me recently. Only thing I can think of having done is upgrading gradle to the latest version.

In the context of LocalInstallation, what is the context of GCM ?

In the example code provided in the API, there is about gcm.register(...) http://apidocs.strongloop.com/loopback-sdk-android/api/index.html. No glue what it is until I found a blog article https://strongloop.com/strongblog/android-push-notifications-loopback-node-js/

Does localInstallation need Google Cloud Messsage to work ?!

My use case is to get static content at application startup, it can change time to time (but not so often). App it self canot change it. Does localInstallation is the best way to solve this requirement ?

Issue with UserRepository.loginuser

Hi there, I have a User model as well as a User Repository set up however when i call the login feature the onError is always called with the message "Expecting a JSON object". Here is the code:

UserRepository userRepo = mAdapter.createRepository(UserRepository.class);
            userRepo.loginUser(mUsername.getText().toString(), mPassword.getText().toString(),
                    new UserRepository.LoginCallback() {
                        @Override
                        public void onSuccess(AccessToken token, User user) {
                            Log.d("TAG", "LOGIN SUCCESS");
                        }

                        @Override
                        public void onError(Throwable t) {
                            Log.d("TAG", "LOGIN FAILURE: " + t.getMessage());
                        }
                    });

Here is the UserRepository (extended from the strongloop UserRepository)

package com.oneset.oneset.model;

public class UserRepository extends com.strongloop.android.loopback.UserRepository<User> {
    public interface LoginCallback extends com.strongloop.android.loopback.UserRepository.LoginCallback<User> {}
    public UserRepository() {
        super("User", null, User.class);
    }

}

If you could shed some help as to what I am doing wrong or missing I would really appreciate it.

Get validation errors from server

I want to register a user in my application via user.save. The data is then validated by the server (especially the uniqueness of the username). If the user inputs invalid data VoidCallback.onError gets called with the exception: org.apache.http.client.HttpResponseException: Unprocessable Entity.

The response body contains Loopbacks error.details.codes which I want to examine in the error handler. How?

Object is null

Reponse from loopback api:

[
  {
    "name": "Receta 1",
    "description": "descripcion de la receta 1",
    "servings": 4,
    "preparing_time": 3847384,
    "cooking_time": 2328738,
    "createdAt": "2015-03-05T16:30:34.000Z",
    "userId": 1,
    "id": 1,
    "user": {
      "firstName": "Bruno",
      "lastName": "Cascio",
      "username": "brunocascio",
      "email": "[email protected]",
      "facebook_id": null,
      "city": null,
      "createdAt": "2015-03-05T16:30:34.000Z",
      "modifiedAt": "2015-03-05T16:30:34.000Z",
      "id": 1
    },
    "likes": [
      {
        "recipeId": 1,
        "userId": 1
      }
    ],
    "ingredients": [],
    "images": []
  }
]

How to define java class for user?

public class Recipe extends Model {
....    
    private User user;
....
}
public class User extends Model {
....    
    private String firstName;
 ....
}

*NOTE: * User model is a custom model, not loopback user.

In java, user throws a NullPointerException

FindById Return Not Found

Hi, I'm beginner in this but I've followed every tutorial there is regarding loopback android sdk. I'm using loopback android sdk ver. 1.5.2 and I've successfully make the login procedure, but I notice that the login doesn't return the user rather it only returns the token. When I confirm it in the explorer it returns the following data :

{
  "id": "nv51KFeWJGjW8O4Q8XrLBkQjWRCrVuMfrvRCpI8N9gEgoPfCMR3FGX3NEcdX3nBy",
  "ttl": 1209600,
  "created": "2015-06-17T13:03:18.917Z",
  "userId": 2
}

so, since I don't get the user data but the user id, I try to get the user data using findById method in user repository, but it returns "HTTP request (string) failed: org.apache.http.client.HttpResponseException: Not Found".

Can anybody explain to me where did I go wrong in this ?

Add support for SNI

Seems like SNI is getting more popular, but the loopj async http lib used in the sdk does not support SNI yet. The square/okhttp project looks like it supports SNI and has an async interface. It also attempts to implement the apache httpclient interface. Any chance that support for this can be added easily? Perhaps drop it in as a replacement for loopj or the apache http lib?

Code cleanup

See android-async-http/android-async-http#751

  1. We now support HEAD requests,
    https://github.com/strongloop/loopback-sdk-android/blob/4587dd82946c6a6647b60bd89ca74ad4ca66a481/src/main/java/com/strongloop/android/remoting/adapters/RestAdapter.java#L303

  2. Your BinaryHandler and CallbackHandler override specific methods, check if you're overriding the ones you want (there are few variants of every callback method, depending on what type of information you do want/need about the request/response processing.

  3. You could probably want to change declarations to require ResponseHandlerInterface instead of AsyncHttpResponseHandler

Add a method to delete a Container?

Maybe I'm overlooking but I don't find any way to delete a Container. I'd expect Container class to have destroy method, but I don't find any. How can I delete a Container (= remove the directory on the server that is associated with the container) ?

Where field value is null or empty

I want to get categories, where parents are equal some categoryId.

  find(ImmutableMap.of(
                "filter",
                ImmutableMap.of("where", ImmutableMap.of("parent",  parent))
        ), callback);

but, when I trying to get categories with no parent, parent == null, it throws NullPointerException

getPackageInfo() and getSharedPreferences() fails

I am seeing these errors on Android 5.0:

  03-13 16:04:59.888    2351-2351/com.colibriapps.foodlr E/BeanUtil﹕ getPackageInfo() failed
      java.lang.IllegalAccessException: Cannot access method: android.content.pm.PackageInfo com.strongloop.android.loopback.LocalInstallation.getPackageInfo()
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.strongloop.android.remoting.BeanUtil.getProperties(BeanUtil.java:94)
              at com.strongloop.android.loopback.LocalInstallation.save(LocalInstallation.java:274)
              at com.colibriapps.foodlr.controller.main.MainActivity.saveInstallation(MainActivity.java:330)
              at com.colibriapps.foodlr.controller.main.MainActivity.updateRegistration(MainActivity.java:279)
              at com.colibriapps.foodlr.controller.main.MainActivity.onCreate(MainActivity.java:87)
              at android.app.Activity.performCreate(Activity.java:5933)
              at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
              at android.app.ActivityThread.access$800(ActivityThread.java:144)
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
              at android.os.Handler.dispatchMessage(Handler.java:102)
              at android.os.Looper.loop(Looper.java:135)
              at android.app.ActivityThread.main(ActivityThread.java:5221)
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
  03-13 16:04:59.888    2351-2351/com.colibriapps.foodlr E/BeanUtil﹕ getSharedPreferences() failed
      java.lang.IllegalAccessException: Cannot access method: android.content.SharedPreferences com.strongloop.android.loopback.LocalInstallation.getSharedPreferences()
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.strongloop.android.remoting.BeanUtil.getProperties(BeanUtil.java:94)
              at com.strongloop.android.loopback.LocalInstallation.save(LocalInstallation.java:274)
              at com.colibriapps.foodlr.controller.main.MainActivity.saveInstallation(MainActivity.java:330)
              at com.colibriapps.foodlr.controller.main.MainActivity.updateRegistration(MainActivity.java:279)
              at com.colibriapps.foodlr.controller.main.MainActivity.onCreate(MainActivity.java:87)
              at android.app.Activity.performCreate(Activity.java:5933)
              at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
              at android.app.ActivityThread.access$800(ActivityThread.java:144)
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
              at android.os.Handler.dispatchMessage(Handler.java:102)
              at android.os.Looper.loop(Looper.java:135)
              at android.app.ActivityThread.main(ActivityThread.java:5221)
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Documentation throws error for User authentification

Using latest Android Studio.
Using this documentation:
http://docs.strongloop.com/display/LB/Android+SDK

Section Users and authentication

This code:

UserRepository userRepo = restAdapter.createRepository(UserRepository.class);

userRepo.loginUser("[email protected]", "password",
new UserRepository.LoginCallback() {
@OverRide
public void onSuccess(AccessToken token, User user) {
// user was logged in
}

   @Override
   public void onError(Throwable t) {
       // login failed
   }

}
);

Produces multiple errors:

  1. restAdapter.createRepository(UserRepository.class); will throw cannot select from parameterized type
  2. I guess this is related to 1)
    image

Please let me know how to solve them

Thanks,
Stephane

loginUser problem

I'm developing an application that uses the Android SDK of Loopback for make REST requests. I have an issue when i try to login a user, I receive that error

08-03 10:44:21.149 12375-12375/com.marcoferraioli.loopback E/Chatome: Login E
org.apache.http.client.HttpResponseException: Not Found
at com.loopj.android.http.AsyncHttpResponseHandler.sendResponseMessage(AsyncHttpResponseHandler.java:404)
at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:161)
at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:178)
at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

I have create User class

package com.marcoferraioli.loopback;

public class User extends com.strongloop.android.loopback.User {
}

and UserRepository class

package com.marcoferraioli.loopback;

public class UserRepository extends com.strongloop.android.loopback.UserRepository<User> {

    public interface LoginCallback extends com.strongloop.android.loopback.UserRepository.LoginCallback<User> {
        }

    public UserRepository() {
        super("admin", null, User.class);
    }

}

this is MainActivity


package com.marcoferraioli.loopback;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.strongloop.android.loopback.AccessToken;
import com.strongloop.android.loopback.RestAdapter;
import com.strongloop.android.loopback.callbacks.ListCallback;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TextView textProva;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textProva = (TextView) findViewById(R.id.prova);

        RestAdapter adapter = new RestAdapter(getApplicationContext(), "http://********:3000/api");

        OperaRepository operaRepository = adapter.createRepository(OperaRepository.class);

        operaRepository.findAll(new ListCallback<Opera>(){ //This work
            @Override
            public void onSuccess(List<Opera> objects) {
                for (Opera opera : objects){
                    textProva.append("\n" + opera.toString());
                }
            }

            @Override
            public void onError(Throwable t) {
                Log.e("Error", "findAll", t);
            }
        });

        UserRepository userRepo = adapter.createRepository(UserRepository.class);

        userRepo.loginUser("[email protected]" , "superadmin" , new UserRepository.LoginCallback() {
            @Override
            public void onSuccess(AccessToken token, User currentUser) {
                textProva.append("\n" + token.getUserId() + ":" + currentUser.getId());
            }

            @Override
            public void onError(Throwable t) {
                Log.e("Chatome", "Login E", t);
            }
        });

    }
}

How I fix this issue?

android-async-http 1.4.5+ not supported

Hi,
I am having one issue while using gradle dependencies. if I use,
compile 'com.strongloop:loopback-sdk-android:1+' (or 1.5.x to be specific) it builds but it fails when the app tries to save a model:

 Process: com.greenfrog.probe, PID: 25918
    java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.
            at com.loopj.android.http.AsyncHttpClient.sendRequest(AsyncHttpClient.java:1096)
            at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:917)
            at com.strongloop.android.remoting.adapters.RestAdapter$HttpClient.request(RestAdapter.java:476)
            at com.strongloop.android.remoting.adapters.RestAdapter.request(RestAdapter.java:204)
            at com.strongloop.android.remoting.adapters.RestAdapter.invokeInstanceMethod(RestAdapter.java:191)
            at com.strongloop.android.remoting.adapters.RestAdapter.invokeInstanceMethod(RestAdapter.java:152)
            at com.strongloop.android.remoting.VirtualObject.invokeMethod(VirtualObject.java:101)
            at com.strongloop.android.loopback.Model.save(Model.java:101)

I guess it was a mismacth of loopj version. so I removed loopj 1.4.5 from sdk dependency and used 1.4.4 as a seperate dependency.

    compile 'com.loopj.android:android-async-http:1.4.4'
    compile ('com.strongloop:loopback-sdk-android:1+'){
        exclude group: 'com.loopj.android' //by artifact name
    }

And no errors anymore. My android studio version is 0.9 and my gradle is 2.2.1
My complete dependency:

   compile 'com.android.support:appcompat-v7:21.0.0'
    compile 'com.google.android.gms:play-services:6.1.71'
    compile 'com.loopj.android:android-async-http:1.4.4'
    compile ('com.strongloop:loopback-sdk-android:1+'){
        exclude group: 'com.loopj.android' //by artifact name
    }

Issue when running Proguard with the SDK (missing documentation)

So this will be a little long since I think I have to give some context. I'm writing this for posterity and for anyone who suffers the same problem I will describe.

Since my firsts steps with LoopBack, I experienced intermittent issues with user persistence in my app. The problem would just not make sense: the user could log in correctly, but after some time, the user would have to log in again, although I could confirm that the token was still saved in the shared preference of the SDK.
Worse, I could not reproduce the problem. No idea where to go from there, and why this could happen. After I had reviewed my code several times, I began to suspect that the SDK itself was causing the issue, but again, I wasn't able to even start debugging the problem (not reproducible, remember?).
The application being a launcher type app, it has a very long lifecycle, increasing the difficulty of isolating the problem.

So, thinking it was an isolated problem that only some users had, I pursued developing the app, until, at some point, I had to write some code that refreshed the user object to check for newly added props added server-side. It was working perfectly on my emulator and my phone. The day following the release, we had multiple user reports that the application was non-functional, and I had to revert my changes in a hurry.

There. I finally had something to work with. I began suspecting the differences between the debug and release builds, so I developed a rapid proof-of-concept app, and I was able to reproduce the issue. Hurray!

Here it is: saveman71/strongloop-sdk-android-proguard-poc

I was then able to finally pinpoint the issue down to these lines in UserRepository, where an AccessToken model, is created from the JSON response from the API. The issue is that the createObject method ultimately uses BeanUtil, to set the properties (here the userId) by using reflexion and calling the appropriate methods for each value in the JSON response, here that would be AccessToken.setUserId().

However, and that's why I wasn't able to reproduce the issue, I'm using proguard to obfuscate the release code that's being published on Google Play. This results in methods and attributes being renamed to very basic names, like a, b, etc. So now BeanUtil is looking for A.setUserId(), whereas the actual method has been obfuscated to something like A.a(), and it fails silently. (expected behaviour in a way, because you can't throw an error for every JSON property that doesn't have its corresponding setter)

All that to say, that there is NEVER, ever, some indication about such behaviour, nor any documentation about how to configure Proguard if we use the SDK.

Finally, the solution was to add the following lines to your proguard-rules.pro file:

-keepclassmembers class * extends com.strongloop.android.loopback.Model {
    public <methods>;
}

This literally says: "Do not obfuscate methods and members that are from classes extending Model"

This problem should really be documented somewhere since I believe (I may be mistaken about this) that Proguard is widely used in production use, and that every library should be aware of issues that code obfuscating could cause to their codebase.

Sorry about the excessively long issue, but I felt like I had to speak my mind about that, no hard feelings, happy to report back to the open source community, so that no one spends an other day debugging that!

Update loopj library

Please update loopj jar to 1.4.6 version. CallBack is not working in 1.4.4(which used here)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.