Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Installation getting deleted by parse server. How to Solve? #1475

Closed
nickkuh opened this issue Apr 13, 2016 · 14 comments
Closed

Installation getting deleted by parse server. How to Solve? #1475

nickkuh opened this issue Apr 13, 2016 · 14 comments

Comments

@nickkuh
Copy link

nickkuh commented Apr 13, 2016

I'm running the latest 2.2.6 parse server with an iOS app written in swift and I'm running into an occasional bug where the server seems to delete a valid installation from the database.

e.g. an installation that originated in the iOS client with the following code:

 let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackground()

I can't pin what exactly causes this issue to occur as it's an edge case. But unfortunately it renders my app pretty unusable for any affected user.

I've searched the issues here and can't see any other reports of this issue. Is it one that you're aware of? I'm guessing that it occurs in the RestWrite class somewhere as there are a few references in there to installations getting destroyed...

As a workaround, what I'd like to do it revoke the session of any effected users when this happens. Is that possible in the server code? I can't find any documentation that describe how to do so?

I can detect the issue in iOS as follows:

let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackgroundWithBlock { (succeed, error) -> Void in
            if (succeed) {

            }
            else if let error = error {
                if error.domain == PFParseErrorDomain {
                    if error.code == PFErrorCode.ErrorObjectNotFound.rawValue {
                        print("What happened to the installation???")
                    }
                }
            }
 }

But there also seems to be no way to get the client to re save a new PFInstallation.currentInstallation(). Any ideas if this is even possible?

Telling the user they need to delete and reinstall the app isn't ideal...

Thanks

Nick

@flovilmart
Copy link
Contributor

Have you got a consistent way to reproduce the issue? Is the PFInstallation locked down by an ACL?

@nickkuh
Copy link
Author

nickkuh commented Apr 13, 2016

Have you got a consistent way to reproduce the issue?

Unfortunately not.

Is the PFInstallation locked down by an ACL?

No.

@flovilmart
Copy link
Contributor

that's quite annoying. We have a way to remove installation duplicates effectively. Without a clear way to reproduce the issues, I can't really investigate more.
On another note, can you try to see if the installation is deleted or if the user just can't access it?

@nickkuh
Copy link
Author

nickkuh commented Apr 14, 2016

Upon further investigation I've found exactly where this problem occurs in parse server:

https://github.com/ParsePlatform/parse-server/blob/master/src/RestWrite.js#L669

And the mongodb query is passing undefined as the not equal installation id. Here's a trace of the delQuery object at the point Parse Server deleted a perfectly valid unique installation object:

{ deviceToken: 'c7e5bc1d506e916388ac7ad577d8b4772cb02a116074bd7232a12e4af7857afc',
  installationId: { '$ne': undefined } }

I've no idea why the installationId is undefined here but presumable a defensive coding check should be added before this code runs?

Hope this helps.

@flovilmart
Copy link
Contributor

That definitely helps, still no luck with having a solid reproduction case?

@nickkuh
Copy link
Author

nickkuh commented Apr 14, 2016

I'm afraid not.

Something to add - the cloud code in our app also makes changes to custom properties of installation objects.

    Parse.Cloud.useMasterKey();
    (new Parse.Query(Parse.Installation)).equalTo("installationId", request.installationId).first()
    .then(
        function(installation) {
            if (installation) {
                //set custom properties
            }
        }
    )

I wonder if that might be the reason that the installationId is undefined when saved server side?

@flovilmart
Copy link
Contributor

that may be actually... I'm not sure. I have a 'fix' that should handle your case, pushing a PR soon.

@nickkuh
Copy link
Author

nickkuh commented Apr 14, 2016

Wonderful - thanks!

Could you also let me know what server side code I can run when one of my effected users connects in order to revoke their session (I've got this handled in the client)?

@flovilmart
Copy link
Contributor

I'm not sure the fix will solve your issue though, that's the problem as we don't have a proper way to reproduce...

I'm not sure I get your question.

@drew-gross
Copy link
Contributor

This should be fixed by #1486

@juliusbtesh
Copy link

I have noticed this happening also. This happened EVERY TIME that I have tried pushing a notification from one user to another of a comment; code that I've taken from Parse AnyPic tutorial. The other two notifications for "Follow" and "Like" work fine, but "Comment" doesn't go through and also removes the "toUser" pointer in the installation class. The only difference between this and the other 2 is that this one has a "badge : Increment" in the payload where the others do not.
Any thoughts?

@CallWhoo
Copy link

I think I'm having the same problem, [PFInstallation currentInstallation] sometime returns null, not sure why its getting deleted.

@kahoona77
Copy link
Contributor

Hi,

I still have an issue with this part. The problem is, that the code tries to delete an installation that might have this deviceToken and that is not equal to the objectID.
But when there is no other installation with this deviceToken then there is nothing to delete and the promise from (this.config.database.destroy('_Installation', delQuery);) is rejected.
This leads to an unhandledRejection Error in node, which is polluding the logs.

If the promise-rejection would be handled with a catch this would not happen.
Or do you have any other idea to work around this?

@flovilmart
Copy link
Contributor

@kahoona77 we'll soon do a pass for those unhandled rejections that are logged starting 6.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants