I'm migrating from Realtime Database to Firestore. Because I can't have both a Realtime Database instance and a Firestore instance in the same project, I have to init the Firestore instance manually, rather than have it pick up the google-services.json file automatically as part of the build. I've done that like this:
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setProjectId("***")
.setApiKey("***")
.setApplicationId("***")
.setDatabaseUrl("https://***.firebaseio.com")
.build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(this, firebaseOptions, "dev");
FirebaseFirestore db = FirebaseFirestore.getInstance(firebaseApp);
All the values are taken from the google-services.json file I downloaded for the new project.
Calling FirebaseFirestore.getInstance() is fine, but when I later try to get a document, I see this in logcat:
W/Firestore: (0.6.6-dev) [OnlineStateTracker]: Could not reach Firestore backend.
The Task for a get() call to a Document has an exception message of:
Failed to get document because the client is offline.
The device is online, for sure. The new project in the console does NOT have the SHA certificate fingerprints set, because I can't use the same one as for the original project.
What am I missing?
[Edit]
I know that is a little late for the answer. In my case, I had the same problem because I try to test Datastore and I lose the possibility to use Firestore in my project. When I try to create a new project for Firestore, I have to init the Firestore instance manually and I had the same problem.
In my case, the problem was that one of the parameters of FirebaseOptions was wrong (in my case was project_id because I had put project_number). I had taken all parameters from google_services.json from the new project:
FirebaseOptions.Builder()
.setApplicationId("X:XXXXXXXX:android:YYYYYYY") // FROM client_info -> mobilesdk_app_id.
.setApiKey("AIzaXXXXXXXXXXX") // FROM api_key -> current_key
.setDatabaseUrl("https://XXXXXXX.firebaseio.com") // FROM firebase_url.
.setProjectId("XXXXXXXX") //FROM project_id
.setStorageBucket("XXXXXXX.appspot.com") //FROM storage_bucket
.build();
After that everything start to work fine.
Related
I want to use FirebaseAnalytics inside a library project on android. I want the events logged to be reported to my Firebase console and not to the console of the app developer. I do not own or control the implementation of the app that will use the library.
Is this possible in any way?
My approach:
I have read this and found out that it is possible to create a FirebaseApp using my credentials as follows:
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("Your AppId") // Required for Analytics.
.setApiKey("You ApiKey") // Required for Auth.
.setDatabaseUrl("Your DB Url") // If you wanted to
.build();
FirebaseApp.initializeApp(context, options, "CompanyA");
Is there a way to use this FirebaseApp to log events as in FirebaseAnalytics?
How do I integrate two Firebase projects within one Android app, so that both will still work independently?
The background:
Within my company's app I was using until now some old Firebase project mainly for GCM purposes. Now the decision within my organization has changed and we decided to move most of the services to the new Firebase project, with higher pricing plan - unfortunately the upgrade wasn't an option.
At this very moment I have:
a legacy project for Cloud Messaging stuff related to some marketing service,
a new Firebase project that will be used for Crashlytics, Remote Config flags and some more.
We don't want to move with Cloud Messaging due to the restrictions the switch causes - all the users would need to register to new notifications channel again. For Marketing reasons that's something unacceptable.
For now I was trying to use the new project's JSON configuration file initialized automagically by Gradle plugin and manual approach to register to the legacy FCM service like this:
FirebaseOptions fo = new FirebaseOptions.Builder()
.setApplicationId(appId)
.setApiKey(apiKey)
.setGcmSenderId(legacySenderId)
.build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(context, fo, "legacy");
HandlerThread thread = new HandlerThread("getLegacyTokenThread");
thread.start();
Handler handler = new Handler(thread.getLooper());
handler.post(() -> {
try {
String token = FirebaseInstanceId.getInstance(firebaseApp).getToken(legacySenderId, "FCM");
L.w("Received token: " + token);
} catch (IOException e) {
e.printStackTrace();
}
});
But this approach seems to be overriding my default project configuration, so the exceptions are not reported to Crashlytics belonging to the new project.
Can anyone suggest how do I make it to run both projects successfully?
Following #Frank's comment above, I didn't manage to make this kind of integration successful.
We ended up in creating a new app in the marketing service that is using new credentials instead of changing the previous ones, what would result in invalidation of the integration. This way we can target both old app's users who didn't update as well as the new ones.
I'm working on an assignment. I've to use Database provided by a provider 'hacker-news'. Also i've to use Firebase Authentication. I've setup a new project in my own account. Retrieving data from Hacker-news database works with below line. I'm able to fetch publicly accessible data with firebase child() APIs is
database = FirebaseDatabase.getInstance("https://hacker-news.firebaseio.com/");
But when i implemented Firebase Authentication and once user logs in it is giving error
Provided authentication credentials are invalid. This usually indicates your FirebaseApp instance was not initialized correctly. Make sure your google-services.json file has the correct firebase_url and api_key
I've spent lot of time on internet and found a link to implement multiple databases in single project -
Working with multiple Firebase projects in an Android app by Google
This works only if you are the owner of those Databases. Is there anyway i can access Hacker-news Database using SDK not REST-API?
FirebaseOptions options = new FirebaseOptions.Builder()
.setDatabaseUrl(getResources().getString(R.string.dbURL))
.setApiKey(getResources().getString(R.string.api))
.setApplicationId(getResources().getString(R.string.appID))
.setProjectId(getResources().getString(R.string.projectId))
.setStorageBucket(getResources().getString(R.string.storageBucket)).build();
//set all variable above as your need
boolean hasBeenInitialized=false;
List<FirebaseApp> fireBaseApps = FirebaseApp.getApps(getApplicationContext());
for(FirebaseApp app : fireBaseApps){
if(app.getName().equals("any_name")){
hasBeenInitialized=true;
}
}
if (!hasBeenInitialized) {
smaTeacher = FirebaseApp.initializeApp(this, options, "any_name");
}
database=FirebaseDatabase.getInstance(FirebaseApp.getInstance("any_name"));
I have an application that is different for each user, id application is different for each user, so idApplication is dynamic. My problem is that json retrieved from firebase is linked to a single application id. How can I use one file json for all the applications I generate dynamically?
_______édit ____
I don't know thé application id, this application id is modified on a filé jenkins.properties on my project Android, and when jenkins générate New apk it do it with thé New id
Instead of relying on google-services.json and associated gradle plugin you can dynamically create FirebaseApp using something like following (I have this in dagger module)
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setApiKey(apiKey)
.setApplicationId(someApplicationId)
.setDatabaseUrl(databaseUrl)
.setStorageBucket(storageBucket)
.build();
firebaseApp = FirebaseApp.initializeApp(context, firebaseOptions, "MyApp");
I'm making an Android app that uses Cloud Endpoints Framework for the backend API. I'm testing the backend using the App Engine development server. In one of the backend functions I try to make a call to get a document from a Firestore database but I get this error:
com.google.api.server.spi.SystemService invokeServiceMethod
SEVERE: exception occurred while calling backend method
java.util.concurrent.ExecutionException: io.grpc.StatusRuntimeException: UNAUTHENTICATED
at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:500)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:479)
at com.google.api.core.AbstractApiFuture.get(AbstractApiFuture.java:57)
...
I believe that I have the service account setup properly. I have the environment variable GOOGL_APPLICATION_CREDENTIALS set to the path of the service account key. I'm also following the guide for instantiating and calling Firestore:
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;
FirestoreOptions firestoreOptions =
FirestoreOptions.getDefaultInstance().toBuilder()
.setProjectId(projectId)
.build();
Firestore db = firestoreOptions.getService();
db.collection(collectionId).get().get();
Is there something I'm missing here to be able to call Firestore from GAE?
After fighting with this issue for some time, I incidentally found a temporary workaround. It seems that the db is indeed not authenticated yet and adding a call after getting the service to get the request meta data seems to trigger the authentification...
Firestore db = firestoreOptions.getService();
try {
// somehow without this it does not work on the local server
db.getOptions().getCredentials().getRequestMetadata();
} catch (IOException e) {
e.printStackTrace();
}
... // db access works on local server!