Error while calling FCM backend service from Google AppEngine - google-app-engine

I am setting up my first app with FCM (we used GCM) and following the tutorials. I have an Android app and a servlet-based app on GAE Standard. To test it a have a servlet that sends a message to the app.
This was working a few hours ago, I could call the servlet and received the test message on the app, but now I am only getting exceptions in the FirebaseMessaging.getInstance().sendAsync(message).get() method
com.google.firebase.messaging.FirebaseMessagingException: Error while calling FCM backend service
and
java.net.UnknownHostException: accounts.google.com
Sometimes one and sometimes the other.
This is the method the GAE servlet calls. I have checked if the token I was using was correct and it is the one currently active in the Android device.
final static String urlFCM = "https://fcm.googleapis.com/fcm/send";
private static void initFCM() {
FileInputStream serviceAccount;
try {
serviceAccount = new FileInputStream("WEB-INF/Orchestram-e2e1ceeb2481.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://orchestram-cerqana.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
e.printStackTrace();
}
/// TODO:
}
public static String sendFCM(final JSONObject value, final String token, final boolean back) {
initFCM();
Message message = Message.builder()
.putData("score", "850")
.putData("time", "2:45")
.setToken(token)
.build();
try {
String response = FirebaseMessaging.getInstance().sendAsync(message).get();
} catch (Exception e) {
e.printStackTrace();
return "ERROR";
}
return "HECHO";
}

Turns out the problem was billing on this specific project on GAE was disabled. Once enabled it worked again (and I'm still bellow the free tier, so no real cost added)

There might be a case where you are subscribing to topics multiple topics at once. There is a exponential back off at firebase. I derived this from the link here.
https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
Topic messaging supports unlimited subscriptions for each topic. However, FCM enforces limits in these areas:
One app instance can be subscribed to no more than 2000 topics.
If you are using batch import to subscribe app instances, each request is limited to 1000 app instances.
The frequency of new subscriptions is rate-limited per project. If you send too many subscription requests in a short period of time, FCM servers will respond with a 429 RESOURCE_EXHAUSTED ("quota exceeded") response. Retry with exponential backoff.

Related

Google App Engine connection request timeout error

I am working on a GAE web app which shows movie related data.To get the movie data I am using API from OMDB (http://www.omdbapi.com/) .Below is the code snippet I use to connect to the API.
When i run it locally it works perfectly fine, but doesn't work when deployed on GAE. It throws connection timeout exception, i tried increasing connection timeout period but that didn't work.
String URLstr = "http://www.omdbapi.com/?t="+URLEncoder.encode(Request,"utf-8");
URL url=null;
URLConnection uc = null;
BufferedReader bf = null;
try {
url= new URL(URLstr);
uc = url.openConnection();
uc.setConnectTimeout(15* 1000);
bf = new BufferedReader(new InputStreamReader(uc.getInputStream()));
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
Is my code incorrect? are there some restrictions with GAE that i missed?
Your code looks correct. I am having the exact same issue with OMDB API and Google App Engine as of a few weeks ago. I reached out to Brian who runs OMDB API regarding this and I think it had to do with the App Engine IP range being blocked because of abuse a few weeks ago.
I created the following webapp to figure out what external IP address the url fetch from my app was showing up as to the OMDB servers. I deployed the following to GAE to get the public IP.
import webapp2
import logging
from google.appengine.api import urlfetch
class ifconfig(webapp2.RequestHandler):
def get(self):
url="http://ipecho.net/plain"
urlfetch.set_default_fetch_deadline(60)
result = urlfetch.fetch(url)
logging.debug("I think my external IP is %s " % result.content)
self.response.write(result.content)
app = webapp2.WSGIApplication([
('/ifconfig', ifconfig)
])
In Google App Engine, I went to the instances tab and shutdown the instance, and checked what external IP the new instance had. I did this several times, and in my case it seemed like the external IPs were all coming from 107.178.195.0/24, so I provided this information to OMDB API.
I guess this was in the banned IP block, and Brian was able to unblock that range. This fixed my issue and requests to the API started working again.
This possibly might have resolved the issue for you as well, but if it didn't, you might want to figure out what your public IP is and reach out to Brian to see if it's in an IP range that's being blocked

Saving GWT form data into different application

I have a GWT application which has form. If user enters data and submit i have to store the data into google datastore and also an JSP application which is running on tomcat server. I found this is done through Task in GAE GAE Push Task from this i am calling a servlet in my gwt application and in that servlet URL fetch There i have to code to send data to another application and call the servlet to insert data. Can anyone give me how to do it(By a simple example). Is this a correct approach or any other way to do this correctly?
I have done it successfully added a push queue task in server side and called a servlet from there which is registered in guice. then in that servlet i called the fallowing lines
Task queue code
Queue queue = QueueFactory.getDefaultQueue();
queue.addAsync(TaskOptions.Builder.withUrl("/userServlet").method(Method.GET).param("userName", userName).param("pwd", pwd).param("mail",mail));
and userservlet has fallowing code to connect to theother application
final String url_Name = "http://xxxxxxxx.com/AddUserServlet";
//final String url_Name = "http://localhost:8181/jos-webapp-1.2.1/AddUserServlet";
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
HTTPRequest request = null;
HTTPResponse response= null;
try{
URL url = new URL(url_Name);
request = new HTTPRequest(url, HTTPMethod.POST);
String body = "userName="+uName+"&pwd="+pwd+"email"+email;
request.setPayload(body.getBytes());
response = fetcher.fetch(request);
}catch(Exception ex){
ex.printStackTrace();
}
In my JOIDS(second application) I wrote a servlet(AdduserServlet) and used someget the data. Any better solution than this will be accepted

How to abort controller action in play framework 2.1 when client cancel request or client socket is closed?

I am testing play framework 2.1 to check what happen when client cancel request or socket is closed from client side. I created this simple program:
package controllers;
import play.;
import play.mvc.;
import views.html.*;
public class Application extends Controller {
public static Result index() {
try{
for(int i=0;i<1000;i++){
Thread.sleep(10000);
System.out.println(i+"\n");
}
}catch(Exception e){
System.out.println("\nexcepción capturada");
}
return ok(index.render("Your new application is ready."));
}
}
If I cancel request from client (google chrome) the loop isn't aborted. I think this could be a problem in real world application, not making a loop, but doing a "heavy" query to database.
Since there was no answer I asked on the google group for play
https://groups.google.com/forum/?hl=en#!topic/play-framework/POvFA3moXug
and here is what James Roper from Typesafe said:
Play offers no such feature. However, there are other ways to achieve
the same thing, for example, if you have a long running request, you
could do it as a websockets request, which let's you easily detect
when the client navigates to a different page.
The latest release as of today is play-2.2.0-RC1 (in case they add support later).

The API package 'channel' or call 'CreateChannel()' was not found

I have a simple web application hosted on tomcat-7 with single servlet. The aim of servlet is to create google channel and then request for a token on opened channel for a user. I have following configuration...
WEB-INF
-- lib
-- appengine-api-1.0-sdk-1.4.3.jar
-- classes
-- Gc.class
The source of Gc.java is...
import com.google.appengine.api.channel.*;
public class Gc extends HttpServlet {
protected void doGetPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Creating channel...<br>");
ChannelService channelService = ChannelServiceFactory.getChannelService();
response.getWriter().write("Channel created!<br>");
response.getWriter().write("Getting token for user 'user1'...<br>");
String token = channelService.createChannel("user1");
response.getWriter().write("toekn => "+token);
}
}
But it gives me an following error...
type Exception report
*message* **The API package 'channel' or call 'CreateChannel()' was not found.**
*description* **The server encountered an internal error (The API package 'channel' or call 'CreateChannel()' was not found.) that prevented it from fulfilling this request.**
exception
com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'channel' or call 'CreateChannel()' was not found.
com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98)
com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:50)
com.google.appengine.api.channel.ChannelServiceImpl.createChannel(ChannelServiceImpl.java:40)
webRtc.Gc.doGetOrPost(Gc.java:46)
webRtc.Gc.doGet(Gc.java:31)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
** Am I missing some libraries? If yes then which and where can I found those.**
Any help is really appreciated.
I got it!!!
The goal of my application is to create google channels and send messages on these channels.
I was under impression that, google channel API is an independent library and was tried to place relevant .jar in lib of my tomcat application.
But I was wrong. Google channel API libraries only works on Google AppEngine Server. And thus, any application needs to leverage these Google APIs must be hosted on Google AppEngine Server.
I am open to listen from experts, if I am wrong.

How to use Twilio with GWT in Google AppEngine (Java)

I was trying to use Twilio's official Java library in my GWT application to send text messages.
Here is the Twilio code I used in my application:
public class TwilioSMS{
/** The Constant ACCOUNT_SID. */
public static final String ACCOUNT_SID = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
public static final String AUTH_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxx";
// Create a rest client
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
/**
* The main method.
*
* #param args
* the arguments
* #throws TwilioRestException
* the twilio rest exception
*/
public String sendMessage(String _to, String _message) throws TwilioRestException
{
// Get the main account (The one we used to authenticate the client
Account mainAccount = client.getAccount();
// Send an sms
SmsFactory smsFactory = mainAccount.getSmsFactory();
Map<String, String> smsParams = new HashMap<String, String>();
smsParams.put("To", _to); // Replace with a valid phone number
smsParams.put("From", "(646) 755-7665"); // Replace with a valid phone // number in your account
smsParams.put("Body", _message);
smsFactory.create(smsParams);
// Make a raw request to the api.
TwilioRestResponse resp = client.request("/2010-04-01/Accounts", "GET",
null);
if (!resp.isError()) {
return resp.getResponseText();
}
else
{
return "Failed to send the message.";
}
}
}
When I ran the code in GAE, I got the following exception:
java.lang.NoClassDefFoundError: javax.net.ssl.KeyManagerFactory is a restricted class. Please see the Google App Engine developer's guide for more details.
I did realize that there is a gwt-twilio http://code.google.com/p/gwt-twilio/ but this is a wrapper for twilio client (which does not handle sending text message)
Any examples that send text messages using twilio in GAE+GWT are helpful!
Thanks
Kun
Twilio Java client library does not on GAE as it obviously uses some Java classes that are not present on GAE.
Since you can not use the Twilio client, your only option is to use GWT-RPC to call your method on server and this method further calls Twilio REST API.
I know this is an old one, but I'd like to share a bit more information if I can. As of January 2014, you can use the Twilio helper library for Java on App Engine if you choose. The Twilio Java library's underlying HTTP client implementation has been modified to run on App Engine.
Also, just to be clear, you should not attempt to use the Twilio helper library on the client side with GWT. The Twilio helper library will only work when the code is executed on the server.
If you want to send an SMS from an App Engine Java app, you will first need to sign up for a Twilio account. Once you have signed up for an account and have your Account SID and Auth Token (found on your dashboard), you can follow this guide in the Google App Engine documentation to set up and configure your environment to send a message.
If you run into any problems, please contact our support squad by e-mailing help#twilio.com.

Resources