strongloop-community / loopback-sdk-android Goto Github PK
View Code? Open in Web Editor NEWAndroid Client SDK for the LoopBack framework.
License: Other
Android Client SDK for the LoopBack framework.
License: Other
Current test cases run server on port 3000, when needed, which crashes other test cases that try to use the same port on same instance causing CI failures.
Goal is to make test server apps port independent.
Parent issue: https://github.com/strongloop-internal/scrum-loopback/issues/932
1.2.0
, while the latest git tag is 1.3.0
.loopback-sdk-android
in the meantime.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
Could someone tell me what is the intended use of the url parameter of loopback.File?
https://github.com/strongloop/loopback-sdk-android/blob/master/src/main/java/com/strongloop/android/loopback/File.java#L25-L34
Maybe I'm missing something but I don't think it is set by anyone. I don't find any code that sets url
nor calls setUrl()
. Its public setter also makes me wonder the intended usage...
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!
Can we extend the SDK Model Object wrappers in the Android SDK in order to directly support the Model's methods related to other Models (e.g. one-to-many etc. structures).
See discussion here: https://groups.google.com/forum/#!topic/loopbackjs/cLE8HXEvmPs
and here: https://groups.google.com/forum/#!topic/loopbackjs/pjWjN_zfHmA
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.
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>
.
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
At the moment, the ModelRepository
class implements only a subset of methods provided by PersistedModel on the server.
Most notably it is not possible to execute find
with a custom filter.
We should improve ModelRepository
and include all built-in methods OOTB.
Related: https://groups.google.com/forum/#!topic/loopbackjs/1xHq5vFRayk
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?
Update the build to the latest Android Studio version. There were breaking changes introduced in newer versions.
Am I right in thinking that there's currently no support for using Google account sign in with the android loopback app sdk? There doesn't appear to be any reference for support within the documentation http://docs.strongloop.com/display/public/LB/Android+SDK.
Is this something I'll have to implement myself? If so how would I go about doing so?
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!
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)
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 -
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?
I am facing socket timeout exception whenever I am trying to upload a little large image or some file through android. How can I increase timeout to prevent socket timeout exception?
Adding compile 'com.strongloop:loopback-android:1.+'
as a dependency creates an error on my gradle:
Error:Module version com.loopj.android:android-async-http:1.4.3 depends on libraries but is not a library itself
Didn't find the way, had to implement the loginUser method from UserRepository and change the "email"
string in the HashMap params to "username"
would be very helpful the option to configure these params for custom user model implementations
UserRepository.java line 228
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".
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:
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:
By doing it this way it covers every case I can think of:
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
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);
}
});
}
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
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...
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#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
Our build system is based on pre-1.0 versions of Android Studio and Build Tools. We need to upgrade it to the latest version, otherwise it's super difficult for new developers to contribute to the project - see e.g. #55 (comment)
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.
Hey!
Are there any plans to add offline synchronization capabilities as described here [1] to the Android/iOS SDKs? I found some google groups threads from 2014 on that topic, but no changes since then. Is this feature already scheduled?
Thank you!
[1] http://docs.strongloop.com/display/public/LB/Synchronization
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 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 ?
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.
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?
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
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 ?
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?
I'm able to use FindAll but how do I get all values for a particular users for a feature like favorites?
See android-async-http/android-async-http#751
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
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.
You could probably want to change declarations to require ResponseHandlerInterface instead of AsyncHttpResponseHandler
Any how to check server available during creating RestAdaptor or createRepository before make the method call to server?
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) ?
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
Looks like this is a problem on the Android SDK side.
When using the methods findById
or findAll
on a model with ID column specified, the id
field in the object returned is null, making it impossible to perform any operation on the model (destroy, for example).
Related question in SO: http://stackoverflow.com/questions/29499567/models-id-not-recognized-when-idinjection-false-and-some-property-has-id
Integrate Eslint to the repo
See the following mailing-list thread:
https://groups.google.com/forum/#!topic/loopbackjs/euQYRSn-KbY
It is not possible to use UserRepository<User>
directly, users always have to create a subclass.
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)
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:
Please let me know how to solve them
Thanks,
Stephane
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?
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
}
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!
Please update loopj jar to 1.4.6 version. CallBack is not working in 1.4.4(which used here)
Hi,
I have configured my loopback app with ssl (https://github.com/strongloop/loopback-example-ssl)
Now, when I try to access any api from android, it gives me the following error.
E/Probe-RegistrationThread(11512): Failed to get remote installation id: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
D/Probe-MainActivity(11512): InstallationCompleteReceiver called
any idea on how can solve this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.