Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an initial test app #16

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Example/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.parse.example" xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET"/>

<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
84 changes: 84 additions & 0 deletions Example/src/main/java/com/parse/example/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.parse.example;

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

import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseLiveQueryClient;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.SubscriptionHandling;
import com.parse.interceptors.ParseLogInterceptor;

import java.net.URI;
import java.net.URISyntaxException;

public class MainActivity extends AppCompatActivity {

String URL = "http://192.168.3.9:1337/parse/";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable named uppercase URL may be confused with the URL class.
String url
I recommend using lowercase to improve readability.

String wsURL = "ws://192.168.3.9:1337/parse/";
String applicationId = "mytest";
String DEBUG_TAG = "debug";

Room mRoom;

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

ParseObject.registerSubclass(Room.class);
ParseObject.registerSubclass(Message.class);

Parse.setLogLevel(Parse.LOG_LEVEL_DEBUG);
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId(applicationId) // should correspond to APP_ID env variable
.clientKey("clientKey") // set explicitly blank unless clientKey is configured on Parse server
.addNetworkInterceptor(new ParseLogInterceptor())
.server(URL).build());

ParseQuery<Room> roomParseQuery = ParseQuery.getQuery(Room.class);
// fixme - why isn't it retrieving
roomParseQuery.whereEqualTo("name", "test");
roomParseQuery.getFirstInBackground(new GetCallback<Room>() {
@Override
public void done(Room room, ParseException e) {
if (e != null) {
Log.d(DEBUG_TAG, "Found exception" + e);
e.printStackTrace();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need deal with the exceptions?

} else {
Log.d(DEBUG_TAG, "Found room: " + room);
}
mRoom = room;

ParseLiveQueryClient parseLiveQueryClient = ParseLiveQueryClient.Factory.getClient();

if (parseLiveQueryClient != null) {
// op=subscribe, className=Message, roomName=test, requestId=1
// op=subscribe, className=Message, roomName=null, requestId=1, order=createdAt
ParseQuery<Message> parseQuery = ParseQuery.getQuery(Message.class);
// FIXME
parseQuery.whereEqualTo("roomName", "test");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should parseQuery.whereEqualTo("room", room);?


// FIXME (rhu) - parse query hates created at
// parseQuery.orderByAscending("createdAt");

SubscriptionHandling<Message> subscriptionHandling = parseLiveQueryClient
.subscribe(parseQuery);
subscriptionHandling.handleEvent(SubscriptionHandling.Event.CREATE,
new SubscriptionHandling.HandleEventCallback<Message>() {
@Override
public void onEvent(ParseQuery<Message> query, Message object) {
Log.d(DEBUG_TAG, "Message" + object);
}
});
}
}
});


}
}
56 changes: 56 additions & 0 deletions Example/src/main/java/com/parse/example/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.parse.example;


import com.parse.ParseClassName;
import com.parse.ParseObject;
import com.parse.ParseUser;

@ParseClassName("Message")
public class Message extends ParseObject {

private final String PARSE_USER_KEY = "parseUser";
private final String AUTHOR_KEY = "author";
private final String MESSAGE_KEY = "message";
private final String ROOM_KEY = "room";

public Message() {

}

public ParseUser getParseUser() {
return getParseUser(PARSE_USER_KEY);
}

public void setParseUser(ParseUser parseUser) {
put(PARSE_USER_KEY, parseUser);
}

public String getAuthorName() {
return getString(AUTHOR_KEY);
}

public void setAuthorName(String authorName) {
put(AUTHOR_KEY, authorName);
}

public String getMessage() {
return getString(MESSAGE_KEY);
}

public void setMessage(String message) {
put(MESSAGE_KEY, message);
}

public Room getRoom() {
return (Room) get(ROOM_KEY);
}

public void setRoom(Room room) {
put(ROOM_KEY, room);
}

@Override
public String toString() {
return String.format("objectId=%s: message=%s room=%s", getObjectId(), getMessage(), getRoom());
}
}
29 changes: 29 additions & 0 deletions Example/src/main/java/com/parse/example/Room.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.parse.example;

import com.parse.ParseClassName;
import com.parse.ParseObject;

@ParseClassName("Room")
public class Room extends ParseObject {

private final String NAME_KEY = "name";

public Room() {

}

String name;

public String getName() {
return getString(NAME_KEY);
}

public void setName(String name) {
put(NAME_KEY, name);
}

@Override
public String toString() {
return String.format("objectId=%s: name=%s", getObjectId(), getName());
}
}
13 changes: 13 additions & 0 deletions Example/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="com.parse.example.MainActivity">

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
Binary file added Example/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Example/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Example/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions Example/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
3 changes: 3 additions & 0 deletions Example/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Example</string>
</resources>
11 changes: 11 additions & 0 deletions Example/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

</resources>
104 changes: 104 additions & 0 deletions ParseLiveQuery/src/main/java/com/parse/OkHttp3WebSocketClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.parse;

import android.util.Log;

import java.net.URI;
import java.util.Locale;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocketListener;
import okio.ByteString;

/* package */ class OkHttp3WebSocketClient implements WebSocketClient {

private static final String LOG_TAG = "OkHttpWebSocketClient";

private final WebSocketClientCallback webSocketClientCallback;
private okhttp3.WebSocket webSocket;
private State state = State.NONE;
private OkHttpClient client;
private final String url;
private final int STATUS_CODE = 200;
private final String CLOSING_MSG = "User invoked close";

private final WebSocketListener handler = new WebSocketListener() {
@Override
public void onOpen(okhttp3.WebSocket webSocket, Response response) {
setState(State.CONNECTED);
webSocketClientCallback.onOpen();
}

@Override
public void onMessage(okhttp3.WebSocket webSocket, String text) {
webSocketClientCallback.onMessage(text);
}

@Override
public void onMessage(okhttp3.WebSocket webSocket, ByteString bytes) {
Log.w(LOG_TAG, String.format(Locale.US, "Socket got into inconsistent state and received %s instead.", bytes.toString()));
}

@Override
public void onClosed(okhttp3.WebSocket webSocket, int code, String reason) {
setState(State.DISCONNECTED);
webSocketClientCallback.onClose();
}

@Override
public void onFailure(okhttp3.WebSocket webSocket, Throwable t, Response response) {
webSocketClientCallback.onError(t);
}
};

private OkHttp3WebSocketClient(WebSocketClientCallback webSocketClientCallback, URI hostUrl) {
this.webSocketClientCallback = webSocketClientCallback;
client = new OkHttpClient();
url = hostUrl.toString();
}

@Override
public synchronized void open() {
if (State.NONE == state) {
// OkHttp3 connects as soon as the socket is created so do it here.
Request request = new Request.Builder()
.url(url)
.build();

webSocket = client.newWebSocket(request, handler);
setState(State.CONNECTING);
}
}

@Override
public synchronized void close() {
setState(State.DISCONNECTING);
webSocket.close(STATUS_CODE, CLOSING_MSG);
}

@Override
public void send(String message) {
if (state == State.CONNECTED) {
webSocket.send(message);
}
}

@Override
public State getState() {
return state;
}

private synchronized void setState(State newState) {
this.state = newState;
this.webSocketClientCallback.stateChanged();
}

/* package */ static class OkHttp3SocketClientFactory implements WebSocketClientFactory {
@Override
public WebSocketClient createInstance(WebSocketClientCallback webSocketClientCallback, URI hostUrl) {
return new OkHttp3WebSocketClient(webSocketClientCallback, hostUrl);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// TODO: add support for fields
// https://github.com/ParsePlatform/parse-server/issues/3671

PointerEncoder pointerEncoder = PointerEncoder.get();
queryJsonObject.put("where", pointerEncoder.encode(state.constraints()));

Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Download [the latest JAR][latest] or define in Gradle:

```groovy
dependencies {
compile 'com.parse:parse-livequery-android:1.0.0'
compile 'com.parse:parse-livequery-android:1.0.1'
}
```

Expand All @@ -39,6 +39,22 @@ ParseLiveQueryClient parseLiveQueryClient = ParseLiveQueryClient.Factory.getClie

### Creating Live Queries

If you wish to pass in your own OkHttpClient instance for troubleshooting or custom configs, you can instantiate the client as follows:

```java
ParseLiveQueryClient parseLiveQueryClient =
ParseLiveQueryClient.Factory.getClient(new OkHttp3SocketClientFactory(new OkHttpClient()));
```

The URL is determined by the Parse initialization, but you can override by specifying a `URI` object:

```java
ParseLiveQueryClient parseLiveQueryClient =
ParseLiveQueryClient.Factory.getClient(new URI("wss://myparseinstance.com"));
```

Note: The expected protocol for URI is `ws` instead of `http`, like in this example: `URI("ws://192.168.0.1:1337/1")`.

Live querying depends on creating a subscription to a `ParseQuery`:

```java
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include ':ParseLiveQuery'
include ':ParseLiveQuery', ':Example'