I'm trying firebase cloud function. I have 1 question any suggestion while greatly appreciate.
I have create http function like below
export const getWelcomeName = functions.https.onRequest((request, response)=>{
})
I have created 1 android app which will call http function with hashmap object contain name of person.
private void getName() {
Map<String, String> data = new HashMap<>();
data.put("name", getIntent().getExtras().getString("username"));
FirebaseFunctions.getInstance()
.getHttpsCallable("getWelcomeName")
.call(data)
.addOnSuccessListener(new OnSuccessListener<HttpsCallableResult>() {
#Override
public void onSuccess(HttpsCallableResult httpsCallableResult) {
snackbar.dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "onFailure: " + e.getLocalizedMessage());
snackbar.dismiss();
}
});
}
How can I return response with appended welcome string using http function
like "Welcome Jake"?
Related
I'm Extending this git'let project to send/receive private messages - targeted only to specific subscribed users. I'm able to send it, but subscribers are not receiving them. I've added the forked full code here, below is a snippet of just the important parts of the code.
Config:
#Configuration
#EnableScheduling
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Autowired
private SessionBasedHandshakeHandler handshakeHandler;
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/queue");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").setHandshakeHandler(handshakeHandler).withSockJS();
}
}
Controller:
#Controller
public class GreetingController {
#Autowired
public SimpMessageSendingOperations messagingTemplate;
private Set<String> users = new HashSet<>();
#GetMapping("/subscribe4PrivateMsgs")
public #ResponseBody String enablePrivateMessages(HttpSession session) {
String sessionId = session.getId();
users.add(sessionId);
return sessionId;
}
#MessageMapping("/hello")
#SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + message.getName() + "!");
}
#Scheduled(fixedDelay = 5000)
private void sendPrivateMessageToScubscribers() {
users.forEach((sessionId) -> {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
String msg = sessionId + ":" + GregorianCalendar.getInstance().getTimeInMillis();
Greeting response = new Greeting(msg);
//Tried the following to Send Private Message, but it doens't works
messagingTemplate.convertAndSendToUser(sessionId, "/queue/private", response,
headerAccessor.getMessageHeaders());
//The following reached UI successfully - but to all users
/*response.setContent("Public Msg:: " + msg);
messagingTemplate.convertAndSend("/topic/greetings", response);*/
});
}
}
UI:
function connect() {
$.get("/subscribe4PrivateMsgs", function(userId) {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting('Received Public Msg: ' + JSON.parse(greeting.body).content);
});
stompClient.subscribe('/user/queue/private', function (greeting) {
showGreeting('1 Received Private Msg: ' + JSON.parse(greeting.body).content);
});
stompClient.subscribe('/user/'+userId+'/queue/private', function (greeting) {
showGreeting('2 Received Private Msg: ' + JSON.parse(greeting.body).content);
});
});
});
}
Turns out that this line was causing issues.
messagingTemplate.convertAndSendToUser(sessionId, "/queue/private", response, headerAccessor.getMessageHeaders());
Changing it to
messagingTemplate.convertAndSendToUser(sessionId, "/queue/private", response);
resolved the issue. Github updated with a working copy.
I'm using meteor ddp (Distributed Data Protocol) to my application. Server code is written using meteor and Android client using java.
Server code
if (Meteor.isServer) {
Users = new Mongo.Collection('testUsers');
Meteor.publish('methodToListen', function(){
return Users.find();
});
}
Client code (https://github.com/delight-im/Android-DDP)
public class MainActivity extends AppCompatActivity implements MeteorCallback {
private Meteor mMeteor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Meteor.setLoggingEnabled(true);
mMeteor = new Meteor(this, "ws://192.168.137.1:3000/websocket");
mMeteor.addCallback(this);
mMeteor.connect();
}
#Override
public void onConnect(boolean signedInAutomatically) {
String subscriptionId = mMeteor.subscribe("methodToListen");
}
#Override
public void onDisconnect() {
}
#Override
public void onException(Exception e) {
}
#Override
public void onDataAdded(String collectionName, String documentID, String newValuesJson) {
Log.d("DATACHANGED", "Add " + collectionName + ", " + documentID + ", " + newValuesJson);
}
#Override
public void onDataChanged(String collectionName, String documentID, String updatedValuesJson, String removedValuesJson) {
}
#Override
public void onDataRemoved(String collectionName, String documentID) {
}
}
So now every client that connects to server see live database updates. Is it possible to send updates only for specific client? So for example when user sign in to system it gets unique id and based on that id is it possible to send updated data?
Updated I can get information about connected clients
Meteor.onConnection(function(connection) {
console.log(connection.id + ", " + connection.clientAddress);
});
So for example ip addresses could be id
UPDATE:
I have learned what I am looking to do is to use the Async within Retrofit with multiple queries too. I have updated my code, but I cannot get the async with the queries.
I am using Retrofit to make my data calls to a movie database and need to change the sort order depending on user settings. I am not clear how I could add this functionality to my interface.
sort_by=highest_rating.desc
or
sort_by=popularity.desc
Interface:
public interface MovieDatabaseApiCient {
#GET("/3/discover/movie")
void getData(#Query("api_key") String apiKey, #Query("sort_by") String sortByValue, Callback<MovieDbModel> response);
}
UPDATED API INTERFACE:
public interface MovieDatabaseApiCient {
#GET("/3/discover/movie?sort_by=popularity.desc&api_key=xxxxxxx")
void getMoviesByPopularityDesc(Callback<MovieDbModel> response);
#GET("/3/discover/movie?sort_by=vote_average_desc&api_key=xxxxxxxx")
void getMoviesByVotingDesc(Callback<MovieDbModel> response);
}
UPDATED DATA CALL THAT WORKS:
private void makeDataCall(String sortPreference) {
final RestAdapter restadapter = new RestAdapter.Builder().setEndpoint(ENDPOINT_URL).build();
MovieDatabaseApiCient apiLocation = restadapter.create(MovieDatabaseApiCient.class);
if (sortPreference.equals(this.getString(R.string.sort_order_popularity)) ){
apiLocation.getMoviesByPopularityDesc (new Callback<MovieDbModel>() {
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
} else {
apiLocation.getMoviesByVotingDesc( new Callback<MovieDbModel>() {
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
}
My call for the data:
private void makeDataCall (String apiKey, String sortPreference) {
final RestAdapter restadapter = new RestAdapter.Builder().setEndpoint(ENDPOINT_URL).build();
MovieDatabaseApiCient apiLocation = restadapter.create(MovieDatabaseApiCient.class);
apiLocation.getData(apiKey, sortPreference, new Callback<MovieDbModel>){
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
I found a way to do Synchronously, but not asynchronously.
From your question and comment, IHMO, you should import retrofit.Callback; instead of import com.squareup.okhttp.Callback;
My code as the following has no compile error:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// creating a RestAdapter using the custom client
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL_BASE)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(mOkHttpClient))
.build();
WebService webService = restAdapter.create(WebService.class);
retrofit.Callback<GetRoleData> callback = new Callback<GetRoleData>() {
#Override
public void success(GetRoleData getRoleData, retrofit.client.Response response) {
}
#Override
public void failure(RetrofitError error) {
}
};
webService.getData("api_key", "sort_by", callback);
}
Interface:
public interface WebService {
#GET("/3/discover/movie")
void getData(#Query("api_key") String apiKey, #Query("sort_by") String sortByValue, Callback<GetRoleData> response);
}
So, please check your code again
I've found several examples on how to pipe and redirect messages from System.out and System.err.
Having decided to develop an application using the JavaFX Webview and Dukescript, I've found useful having one place where to display all messages, i.e. the Firebug Lite console.
See below.
PS This is the exact opposite as this
First define an abstract class
public abstract class FirebugConsole extends OutputStream {
abstract void log( String msg );
StringBuilder sb = new StringBuilder();
#Override
public void write(int i) {
sb.append((char)i);
}
#Override
public void flush() {
if( sb.length() >0 && !sb.toString().equals("\r\n"))
log(sb.toString());
sb = new StringBuilder();
}
}
Then extend it with methods that implement native calls into JavaScript. Here's for example how to write log messages
public class FirebugConsoleInfo extends FirebugConsole{
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.log(msg);")
public native void log( String msg );
}
Finally, pipe System.out and System.err to those objects
public static void onPageLoad() throws Exception {
...
System.setOut(new PrintStream(new FirebugConsoleInfo(), true));
System.setErr(new PrintStream(new FirebugConsoleError(), true));
...
}
Note: for some reasons the usual console.log() doesn't work for me, I know Firebug doesn't bind a console if a console object is already present, so I suspect the WebFX webview must itself pipe console.log messages to System.out in the first place.
Update
The solution above doesn't work when the messages are generated by a thread other than the browser's. Here's an updated solution based on BrwsrCtx.execute()
public abstract static class FirebugConsole extends OutputStream {
protected final BrwsrCtx ctx;
public FirebugConsole( BrwsrCtx ctx ){
this.ctx = ctx;
}
abstract void logNative( String msg );
void log(String msg) {
ctx.execute(new Runnable(){
#Override
public void run() {
logNative(msg);
}
});
}
StringBuilder sb = new StringBuilder();
#Override
public void write(int i) {
sb.append((char)i);
}
#Override
public void flush() {
if( sb.length() >0 && !sb.toString().equals("\r\n"))
log(sb.toString());
sb = new StringBuilder();
}
}
public static class FirebugConsoleInfo extends FirebugConsole{
public FirebugConsoleInfo(BrwsrCtx ctx) {
super(ctx);
}
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.log(msg);")
public native void logNative( String msg );
}
public static class FirebugConsoleError extends FirebugConsole{
public FirebugConsoleError(BrwsrCtx ctx) {
super(ctx);
}
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.error(msg);")
public native void logNative( String msg );
}
}
and
public static void onPageLoad() throws Exception {
BrwsrCtx ctx = BrwsrCtx.findDefault(GoGPS_Fx.class);
System.setOut(new PrintStream(new FirebugConsoleInfo(ctx), true));
System.setErr(new PrintStream(new FirebugConsoleError(ctx), true));
}
Note: it's quite slow for large logs, there might be faster alternatives (StringWriter is one). But I suspect the bottleneck is the passing of messages back and forth from Java to JavaScript.
I'm using Retrofit and RxJava but can't seem to do what I want.
Here's my declaration of my web service:
Observable<Response> rawRemoteDownload(#Header("Cookie") String token, #Path("programId") int programId);
The problem I have is the webservice is returning a 403 and a json payload with details.
Retrofit calls onError, only passing the Throwable so I can't check the response body.
Here's part of my test code
apiManager.rawRemoteDownloadRequest("token", 1).subscribe(new Observer<Response>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
// this is called and I've lost the response!
}
#Override
public void onNext(Response response) {
}
});
SOLUTION:
Thanks to Gomino, I went with this as a solution:
new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
if (throwable instanceof RetrofitError) {
Response response = ((RetrofitError) throwable).getResponse();
System.out.println(convertToString(response.getBody()));
}
}
where convertToString looks like:
private String convertToString(TypedInput body) {
byte[] bodyBytes = ((TypedByteArray) body).getBytes();
return new String(bodyBytes);
}
Check if the throwable is a RetrofitError:
#Override
public void onError(Throwable e) {
if (e instanceof RetrofitError) {
Response response = ((RetrofitError) e).getResponse();
}
}