12

Problem Description

My Android app collects data via Google Analytics for Firebase. For privacy reasons, users must be able to wipe their data off the Firebase servers, should they choose to do so.

The app requests a deletion by forwarding its Firebase APP_INSTANCE_ID to my own server. This server has been prepared in advance with credentials, from my personal Google account (via oauth2), for managing the Firebase project. The server authenticates with www.googleapis.com, and, using the supplied APP_INSTANCE_ID, invokes the upsert.

As noted by the documentation, the generic Google Analytics API is appropriate for this task.

After some initial trouble (b/c I didn't have the correct auth scope, and the Analytics API wasn't properly enabled), googleapis.com now returns HTTP 200 for each upsert request. (As an aside, even if you supply a bogus APP_INSTANCE_ID, it returns 200.)

Here is a sample response from the upsert, which shows nothing amiss:

{ kind: 'analytics#userDeletionRequest',
  id: 
   { type: 'APP_INSTANCE_ID',
     userId: (REDACTED 32-char hexidecimal string) },
  firebaseProjectId: (REDACTED),
  deletionRequestTime: '2018-08-28T12:46:30.874Z' }

I know the firebaseProjectId is correct, because if I alter it, I get an error. I have verified that the APP_INSTANCE_ID is correct, and stable up until the moment it is reset with resetAnalyticsData().

Test Procedure

To test the deletions, I populated Firebase with several custom events, using the procedure below (Nexus 5X emulator, no Google Play, no Google accounts configured, but that shouldn't make any difference):

  1. Install the app
  2. Fire off some custom events (FirebaseAnalytics.logEvent)
  3. Observe those events appear on the Firebase console
  4. (About a minute later:) Make the upsert call, observe HTTP 200, and note the "deletionRequestTime"
  5. Immediately call FirebaseAnalytics.resetAnalyticsData (to clear any event data cached on the device)
  6. Uninstall the app
  7. Rinse & repeat 7 or 8 times

However, even 24 hours later, 100% of the Firebase events are still present in the events table. No discernable state change has taken place on the Firebase server as a result of the upserts.

Question

So, what am I doing wrong? how do I successfully delete user data from Google Analytics for Firebase?

EDIT

Here's the code I'm using to make a request (from node.js):

const request = require( 'request' ); 

... 

_deletePersonalData( data ) 
{ 
    return new Promise( (resolve, reject) => { 
        request.post({ 
            url: 'https://www.googleapis.com/analytics/v3/userDeletion/userDeletionRequests:upsert', 
            body: { 
                kind: 'analytics#userDeletionRequest', 
                id: { 
                    type: 'APP_INSTANCE_ID', 
                    userId: data.firebaseAppInstanceId 
                }, 
                firebaseProjectId: (REDACTED) 
            }, 
            headers: { 
                Authorization: 'Bearer ' + iap.getCurAccessToken() 
            }, 
            json: true 
        }, (err, res, body) => { 
            console.log( 'user-deletion POST complete' ); 
            console.log( 'Error ' + err ); 
            console.log( 'Body ', body ); 

            if( err ) 
            { 
                reject( err ); 
                return; 
            } 

            if( body.error ) 
            { 
                reject( new Error( 'The Google service returned an error: ' + body.error.message + ' (' + body.error.code + ')' ) ); 
                return; 
            } 

            resolve({ deletionRequestTime: body.deletionRequestTime }); 
        }); 
    });
} 

Here's a sample request body:

{
  kind: 'analytics#userDeletionRequest',
  id: {
    type: 'APP_INSTANCE_ID',
    userId: (REDACTED 32-char hexidecimal string)
  },
  firebaseProjectId: (REDACTED)
}

And here's the console output for that same request (same userId and everything):

user-deletion POST complete
Error: null
Body: { kind: 'analytics#userDeletionRequest',
  id: 
  { type: 'APP_INSTANCE_ID',
    userId: (REDACTED 32-char hexidecimal string) },
  firebaseProjectId: (REDACTED),
 deletionRequestTime: '2018-08-29T17:32:06.949Z' }
greeble31
  • 4,398
  • 2
  • 11
  • 27
  • 1
    This should have worked. You need to reachout to the Firebase Support for additional help. Please also provide the request via upset API - https://firebase.google.com/support/contact/?category=troubleshooting – AniV Aug 28 '18 at 23:18
  • FWIW, my experiences are similar - the requests worked eventually, but it took an inane amount of time (several days) before anything happened. – Eike Pierstorff Aug 30 '18 at 07:43
  • FYI I am currently waiting on a response from Firebase Support. And, no deletions have been observed to date. – greeble31 Aug 31 '18 at 13:30
  • please edit your question and include the request that you are making. I need more then just the response. – DaImTo Sep 04 '18 at 13:15
  • @DalmTo edited as requested, let me know if I left anything out – greeble31 Sep 04 '18 at 13:38
  • is that error coming from body or google ? – Ahmed amin shahin Sep 06 '18 at 22:24
  • ok i think i got the issue .. i will post soon – Ahmed amin shahin Sep 06 '18 at 22:49
  • @AhmedShahin ? No error exists. The problem is that no records are being deleted. – greeble31 Sep 06 '18 at 23:20
  • @greeble31 the last code on post , error : null ; from where its coming ? – Ahmed amin shahin Sep 06 '18 at 23:29
  • you will need to use your client id which u created for the application as i understand from google documentation not the client user id ...to authorize your request .. i might be wrong .. but this is how i understood it – Ahmed amin shahin Sep 06 '18 at 23:32
  • @AhmedShahin Ah, I see what you're asking; it actually comes from the line `console.log( err );`. Mismatch between the code I posted and the log dump. I'll edit the question. – greeble31 Sep 06 '18 at 23:35
  • look , in my entire life , i never faced an issue on this field without solving it .. so am going to solve your issue hhhhh .. but please if you allow me , can we open a chat room and discuss this there ? – Ahmed amin shahin Sep 06 '18 at 23:37
  • @AhmedShahin I appreciate that, you can feel free to open a chatroom if you wish, but I think this is going in one particular direction: The only people who can help me are those with detailed knowledge of this particular API, whether that is because they're been through this before, or because they're on the Firebase team at Google. I've used similar APIs without any problems, and the fact that there is no error code suggests a problem with either A.) the documentation or B.) something that neither of us are ever going to guess. – greeble31 Sep 06 '18 at 23:44
  • @greeble31 i agree with you but also those who solved that did not know how to resolve it and some of them figured it out ... let me ask you this please have you thought about the issue could be firebase indexing issue ? – Ahmed amin shahin Sep 06 '18 at 23:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/179601/discussion-between-ahmed-shahin-and-greeble31). – Ahmed amin shahin Sep 06 '18 at 23:54
  • @greeble31 this might work for you if you used it before making the cache clear but there is additional steps too , have you tried it FirebaseDatabase.getInstance().setPersistenceEnabled(true); – Ahmed amin shahin Sep 06 '18 at 23:55

1 Answers1

3

Firebase support just got back to me, and I quote:

Upsert method deletes any individual user data we have logged, but aggregate metrics are not recomputed. This means that you might not see any changes in the events tab in your Analytics console.

So, basically my mistake was expecting the events to disappear from the console.

This, of course, raises the question of how one determines that the API is actually working... but maybe the HTTP 200 is enough.

greeble31
  • 4,398
  • 2
  • 11
  • 27