I want to access Firestore's real-time database inside of my Google App Engine project as an additional database.
What is the best way to write to Firestore from a Google App Engine backend? Would using the Firestore Rest API be decent? Or is there a better method?
How would authentication work between the two projects? Since as far as I understand a Google App Engine project and Firestore project are two separate things.
Yes, the best practice is to use the Firestore Rest API.
Concerning the authentication, the app engine service has its default service account which you can find on the app engine page.
Simply grant permissions to this service account on the project B to access & write firestore and the Lib SDK will smoothly handle everything!
Which language are you using ? So I could edit my answer with a demo code
Edit 1:
You may misunderstand the concept of projects. A project is an envelope where you can use services. IN this example: you can have a single GCP project containing your firestore and your App Engine.
Edit 2:
As I thought, there's a code sample on the Google demo repo. Check this out !
https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/firestore
The best way to access Google Cloud Firestore is using its client libraries (rather than the REST API). I mean, you could use the REST API, there's nothing wrong w/that at all, however it generally involves more coding on your part whereas the client library does more of the heavy-lifting.
With the client library, setting up an API client is a 1-liner, then accessing it is straightforward. Here's a code snippet for a simple web app that tracks all website visits just to show you basic usage (works on 2.x & 3.x):
'fs_visits.py -- Cloud Firestore sample Python snippet for web visit registry'
from __future__ import print_function
from datetime import datetime
from google.cloud import firestore
def store_visit(timestamp):
visits = fs_client.collection('visitX')
visits.add({'timestamp': timestamp})
def fetch_visits(limit):
visits = fs_client.collection('visitX')
return visits.order_by(u'timestamp',
direction=firestore.Query.DESCENDING).limit(limit).stream()
TOP = 10 # limit to 10 results
fs_client = firestore.Client() # create Cloud Firestore client
if __name__ == '__main__':
print('** Adding another visit')
store_visit(datetime.now()) # store a "visit" object
print('** Last %d visits' % TOP)
times = fetch_visits(TOP) # fetch most recent "visits"
for obj in times:
print('-', obj.to_dict()['timestamp'])
Here's the sample output I got when I ran it:
$ python fs-snip.py
** Adding another visit
** Last 10 visits
- 2020-03-23 09:14:09.742027+00:00
- 2020-03-11 01:06:47.103570+00:00
- 2020-03-11 01:03:29.487141+00:00
- 2020-03-11 01:03:16.583822+00:00
- 2020-03-11 01:02:35.844559+00:00
- 2020-03-11 00:59:51.939175+00:00
- 2020-03-11 00:59:39.874525+00:00
- 2020-03-11 00:58:51.127166+00:00
- 2020-03-11 00:58:34.768755+00:00
- 2020-03-11 00:58:21.952063+00:00
It doesn't explain much, but if you can figure out the code, you'll have an idea of how it works. Here's the official Quickstart tutorial and a follow-on deeper dive tutorial that goes over everything in much more detail than my little code snippet.
FWIW, I tried coming up with the same thing but using the REST API and ran into some perms problem (403). Maybe I'll revisit again later. (It was too difficult for me to accomplish just trying for 15-20 minutes.)
As far as projects go, a Google Cloud (Platform) project is a singular, logical entity for an application and its resources. At this time, every project can have one App Engine app and one NoSQL database (Cloud Datastore [now called Cloud Firestore in Datastore mode] or Cloud Firestore [referred to as Cloud Firestore in Native mode]... you pick). This means they can both be in the same project so you wouldn't have to worry about cross-project permissions.
Related
I'm trying to migrate an a web app from Google Appengine to a dedicated server and I've got stuck to the logging issue. Basically I would like to organise the logs per request/context(like on GAE) so that I can easily review the errors/trace on each request. The most advanced logging library I could find is the glog package but still I can't figure it out how to log per request/context.
Each request gives you a http.Request-object to work with.
If you're using sessions, then you'll have a sessions.Session-object to work with.
You will want to use those objects to help log per request/context, as they identify the request / session.
Suddenly my gapi client stopped sending request params to endpoint.
This is how my code looks like
Load the gapi JS
https://apis.google.com/js/client.js?onload=initGoogleApis
in initGoogleApis
function initGoogleApis() {
var ROOT = HOST + "/_ah/api";
gapi.client.load("userendpoint", "v1", function() {
userendpoint = gapi.client.userendpoint;
}, ROOT); }
Now when I query userendpoint.<some function>, then it is not passing the request params to endpoint
NOTE: it was working fine till today morning.
Anyone else facing the same issue? (this might be due to some update in the gapi library)
This issue has been resolved as of yesterday 2014-09-23 08:00 (US Pacific Time).
Details about this issue can be found in the Google App Engine Downtime Notify Group
However 'Google APIs Client Library for JavaScript' is still in Beta and breaking changes have been rolled out more than once. Clound Endpoints themselves are out of beta and can be used for production use.
Now, to properly answer this questions:
The simple advice here is: Don't use beta products for production applications.
To avoid problems with Google APIs Client Library for JavaScript, just don't use it. You can write your own REST API client that will not be affected by changes to the JavaScript library from Google. I have done this for testing purposes a couple of times and it is not hard, just a lot of work depending on how many endpoints you have and how complex they are.
We have the same problem on two projects.
I think that Google has deoployed a new version of the "https://apis.google.com/js/client.js" and it dosen't works as expected...
We need to open a ticket to Google support. If I have any news I will report them to you.
Google reports (https://groups.google.com/forum/#!topic/google-appengine-downtime-notify/t9GElAJwj8U):
We are currently experiencing an issue with Google Cloud Endpoints where the GAPI Javascript client is unable to pass request parameters. For everyone who is affected, we apologize for any inconvenience you may be experiencing. We will provide an update by Tuesday, 2014-09-23 05:00 (all times are in US/Pacific) with current details, and if available an estimated time for resolution.
Update:
We have fixed the issue affecting Google Cloud Endpoints JavaScript client and are gradually rolling-out a fixed version. We estimate full resolution of the issue by 06:30 US/Pacific Pacific. We will provide an update by 06:00 AM.
Update:
Now it works for me.
Marco
I keep getting the following message when trying to deploy the sample application from within Eclipse. I tried to post an image of my Application settings but being a newbie it wouldn't let me.
------------ Deploying frontend ------------
com.google.appengine.tools.admin.HttpIoException: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=http%3A%2F%2Fgdbguesttest.appspot.com%2F&version=1&
400 Bad Request
Here is a copy and paste from the application settings:
Application Identifier Alias:
gdbguesttest.appspot.com
Between 6 and 30 characters. Provides an alternative URL to access your application through appspot.com. It can be used to enable Channel, XMPP, Email, and SSL access for your application.
http://gdbguesttest.appspot.com
Datastore Replication Options:
High Replication
Uses a highly replicated Datastore that synchronously replicates data across multiple locations simultaneously.
OK found my problem. You only should put your app ID, not the entire path.
So in my case.
gdbguesttest
NOT
http://gdbguesttest.appspot.com
i tried to use the custom search api ( http://code.google.com/intl/de-DE/apis/websearch/docs ) with java. it works perfectly on eclipse on my local machine.
when i try to do the same from google app engine the reply is: {"responseData": null, "responseDetails": "Quota Exceeded. Please see http://code.google.com/apis/websearch", "responseStatus": 403}
i do not understand. isn't it possible to call search api from GAE apps?
If you look at the very top of that page you linked to, they note that the API has been deprecated and the number of search queries you can make is limited.
However, if you absolutely NEED to use that API instead of the Custom Search API as Google suggests, there are a few troubleshooting steps you can take:
1) Check that your API key is unique to the project, and the limited number of queries you're allowed isn't being consumed by some other application.
2) Google does (did?) hostname filtering so that one computer doesn't use up all the API requests. You may be able to move the queries to Javascript instead of Java -- essentially move the request from the server to the client.
3) Try using a named backend (Java Backends)
The CherryPy web server can supposedly be deployed in the Google App Engine.
Who has done it, and what was the experience like?
What special effort was required (configuration, etc.)?
Would you recommend it to others?
The article is a good example but its slightly out of date now as the patch is no longer required, the latest version of Cherrypy should run without it, I've gotten the sample below running in the development environment.
I've included cherrypy inside a zip file as the google app engine has a limit of one thousand files per application, it also makes it easier to deploy.
I'm also using the cherrypy dispatch handler to route the request.
import sys
sys.path.insert(0, 'cherrypy.zip')
import cherrypy
import wsgiref.handlers
class Root:
exposed = True
def GET(self):
return "give a basic description of the service"
d = cherrypy.dispatch.MethodDispatcher()
conf = {'/':
{
'request.dispatch': d
}
}
app = cherrypy.tree.mount(Root(), "/",conf)
wsgiref.handlers.CGIHandler().run(app)
So far I've not come across any particular issues but I have read some people have had issues with sessions.
See boodebr.org article (missing, but here on the Wayback machine) It works for me.
If you are looking for an example, look for the condition that accepts ServerMode.GAE in ServerInterface.auto in this example.
There is a good article on how to do this over here now here. I haven't actually tried this yet, I stuck with django on App Engine, but it seems to be a solid example.