2016-05-20 8 views
1

Ich habe Probleme, die Tokens, die ich an meinen Server sende, erfolgreich zu verfolgen. Die Token werden für GCM-Benachrichtigungen in einer Android App verwendet.SQL Server: Datensatzhandhabung erforderlich

Das Szenario ist dies: Wenn ein Benutzer die App installiert, erstelle ich ein GCM-Token, speichern Sie es in freigegebenen Einstellungen und senden Sie es an meinen Server zum Speichern, damit ich eine Benachrichtigung zu einem späteren Zeitpunkt senden kann. Dieser Teil ist einfach. Kein Problem, das Token auf meinem Server zu speichern und die App-Benutzer anrufen. Ich kann allgemeine Benachrichtigungen an Endbenutzer senden, die kein Konto in der App registriert haben.

Wenn der Benutzer ein Konto registriert und sich bei seinem Konto angemeldet hat, aktualisiere und verknüpfe ich die Benutzer-ID mit dem Token. Dies hilft mir, wenn ich bestimmte Benachrichtigungen an einen einzelnen App-Benutzer senden möchte. Noch so einfach.

Hier ist meine Tabellen und gespeicherte Prozedur für die Aktualisierung

CREATE TABLE NOTIFICATION 
(
    MESSAGEID INT IDENTITY NOT NULL, 
    TOKEN VARCHAR(255) NOT NULL PRIMARY KEY, 
    UID VARCHAR(128) NULL UNIQUE, 
    USTAMP SMALLDATETIME NOT NULL, --know when token is updated 
    ISTAMP SMALLDATETIME NOT NULL --know when token was created 
) 

CREATE PROCEDURE [dbo].[spGCMupdate] 
    @T VARCHAR(255), 
    @U VARCHAR (128), 
    @RESULT TINYINT OUTPUT 
AS 
BEGIN 
    --DECLARE @iU int 
    --DECLARE @iT int 
    --SET @iT = (SELECT COUNT(TOKEN) FROM NOTIFICATION WHERE TOKEN = @T) 
    --SET @iU = (SELECT COUNT(UID) FROM NOTIFICATION WHERE UID = @U) 

    UPDATE NOTIFICATION 
    SET UID = @U, USTAMP = DATEADD(HH, 3, GETDATE()) 
    WHERE UID IS NULL 
     AND TOKEN = @T --add uid to token 

    IF (@@ROWCOUNT = 0) 
    BEGIN 
     UPDATE NOTIFICATION 
     SET TOKEN = @T, USTAMP = DATEADD(HH, 3, GETDATE()) 
     WHERE UID = @U -- handle a token update 
    END 

    IF (@@ROWCOUNT = 0) 
    BEGIN 
     DECLARE @i int 
     SET @i = (SELECT COUNT(TOKEN) FROM NOTIFICATION WHERE TOKEN) 

     INSERT INTO NOTIFICATION(TOKEN, UID, USTAMP, ISTAMP) 
     VALUES (@T, @U, DATEADD(HH, 3, GETDATE()), DATEADD(HH, 3, GETDATE())) --Insert new combo 
    END 

    IF (@@ROWCOUNT > 0) 
    BEGIN  
     SET @RESULT = '1' 
    END 
    ELSE IF (@@ROWCOUNT = 0) 
    BEGIN 
     SET @RESULT = '0' 
    END 

    SELECT @RESULT 
END 
GO 

CREATE PROCEDURE [dbo].[spGCMinsert] 
    @T VARCHAR(255), 
    @U VARCHAR (128) = NULL, 
    @RESULT TINYINT OUTPUT 
AS 
BEGIN 
    INSERT INTO NOTIFICATION(TOKEN, UID, USTAMP, ISTAMP) 
    VALUES (@T, @U, DATEADD(HH, 3, GETDATE()), DATEADD(HH, 3, GETDATE())) 

    IF (@@ROWCOUNT > 0) 
    BEGIN  
     SET @RESULT = '1' 
    END 
    ELSE 
    BEGIN 
     SET @RESULT = '0' 
    END 

    SELECT @RESULT 
END 
GO 

Es ist die GCMupdate gespeicherte Prozedur das ich habe Probleme mit. Ich installiere die App zum ersten Mal und ich habe jetzt ein Token. Gute Sachen .. Dann melde ich mich an und melde mich an, jetzt habe ich ein Token mit einer Benutzerkennung. Ausgezeichnet ... Dann kaufe ich ein neues Handy und lade die App herunter. Neues Token generiert und gespeichert, das Problem ist, wenn ich mich anmelde und versuche, das neu erstellte Token zu aktualisieren Ich habe bereits eine Benutzer-ID in der Tabelle gespeichert. Ich bin mir nicht sicher, ob die UID eindeutig der beste Ansatz ist.

Ich bin mir nicht sicher, ob ich meinen Tisch anders aufstellen sollte. Ich weiß, dass ich sicherstellen möchte, dass ich die Token ohne Fehler im Auge behalten kann. Ich denke, ich brauche einige Löschanweisungen einige in der gespeicherten Prozedur, nicht sicher.

Jede Hilfe oder Vorschläge würden sehr geschätzt werden.

+0

Grundsätzlich UID ist nicht eindeutig in der Tabelle, da eine bestimmte UID mehrere Tokens haben kann. Gibt es eine andere Verarbeitung, die erfordert, dass sie einzigartig ist? Beabsichtigen Sie eine Erlaubnis, dass USERID Ihre App auf vielen Geräten (Tokens?) Aktiv nutzen darf. Ist das Problem, dass Sie nur jeweils ein aktives Gerät gleichzeitig benachrichtigen möchten? Ich denke, deine Fehlermeldung ist etwas über die Einzigartigkeit. Die praktische Lösung ist, die einzigartige Einschränkung zu entfernen, aber welche Downstream-Wirkung hat das? Welche anderen Prozesse brauchen dies, um einzigartig zu sein? –

+0

Die App wird nur auf Smartphones mit Bluetooth verwendet und hauptsächlich nur vor Ort (an der Autowaschanlage, für die die App bestimmt ist) verwendet. Es müssen nicht mehrere Geräte Benachrichtigungen empfangen. Es ist ein wenig kompliziert. Wir könnten beide die App auf unseren Handys haben und jeder hat getrennte Konten. Heute benutze ich dein Handy bei der Waschanlage, weil mein Akku leer ist und ich nach dem Waschen meine Benachrichtigungen erhalten möchte. Aber morgen benutze ich wieder mein Telefon, ich möchte, dass ich meine Benachrichtigungen auf meinem Handy und nicht auf deinem Handy bekomme. Deshalb aktualisiere ich das Token beim Anmelden mit der Benutzerkennung.Vielen Dank –

+0

Wenn Sie nicht möchten, Geschichte zu speichern und an alte Geräte zu erinnern und Sie möchten nur automatisch auf das neue Gerät verschieben, dann sollten Sie ändern Sie proc, um das _token_ zu aktualisieren, wenn die Benutzer-ID bereits gefunden wird. Scheint dies Ihren Anforderungen zu entsprechen? –

Antwort

2

Dies könnte prägnanter sein. Es verwendet RETURN statt SELECT, um sofort zu beenden, löst einen Fehler für einen unerwarteten Zustand aus. Es wird auch davon ausgegangen, dass USTAMP und ISTAMP einen Standard definiert haben. Ich bin mir nicht sicher, warum Sie 3 Stunden hinzufügen, aber Sie möchten vielleicht in zeitzonenbewusste Datentypen schauen.

CREATE PROCEDURE [dbo].[spGCMupdate] 
@T VARCHAR(255), 
@U VARCHAR (128) 
AS 
BEGIN 
    -- If this is a new user against existing token, update it 
    UPDATE NOTIFICATION 
    SET 
    USTAMP = DATEADD(HH, 3, GETDATE()), 
    USER = @U 
    WHERE TOKEN = @T 
    AND (USER IS NULL OR USER <> @U) 

    IF @@ROWCOUNT > 0 
     RETURN 1 

    -- If this is an existing user against a different token 
    -- change the token 
    UPDATE NOTIFICATION 
    SET 
    USTAMP = DATEADD(HH, 3, GETDATE()), 
    TOKEN = @T 
    WHERE USER = @U 
    AND TOKEN <> @T 

    IF @@ROWCOUNT > 0 
     RETURN 2 

    -- Completely new 
    INSERT INTO NOTIFICATION(TOKEN, UID) 
    SELECT @T, @U 
    WHERE NOT EXISTS (
     SELECT * FROM NOTIFICATION 
     WHERE TOKEN = @T 
     AND USER = @U 

    IF @@ROWCOUNT > 0 
     RETURN 3 


    IF EXISTS (
     SELECT * FROM NOTIFICATION 
     WHERE TOKEN = @T 
     AND USER = @U 
     ) 
     RETURN 4 -- Already exists. No change 

    THROW 60000 ,'Unexpected State encountered' 
END 
+0

Gute Information. Vielen Dank! –

0

Vielen Dank für die Vorschläge Nick. Es hat mir geholfen, eine Lösung zu finden. Ich weiß nicht, ob das die beste Lösung ist, aber es scheint alle Anforderungen zu erfüllen und es ist das Beste, was ich heute Abend habe. Vielleicht werde ich mit etwas Schlaf etwas Besseres einfallen lassen. Ich bin sicher, es gibt Raum für Verbesserungen.

CREATE PROCEDURE [dbo].[spGCMupdate] 
@T VARCHAR(255), 
@U VARCHAR (128), 
@RESULT TINYINT OUTPUT 
AS 
BEGIN 
    DECLARE @PAIR int 
     SET @PAIR = (SELECT COUNT(TOKEN) FROM NOTIFICATION WHERE TOKEN = @T AND UID = @U) 

    IF (@PAIR = 1) -- the Token and Userid are already paired no update required 
      BEGIN 
      SET @RESULT = '1' -- all good 
      END 
    ELSE IF (@PAIR = 0) -- attempt to pair 
       BEGIN 
      UPDATE NOTIFICATION SET UID = @U, USTAMP = DATEADD(HH, 3, GETDATE()) WHERE UID IS NULL AND TOKEN = @T --add uid to token 
       END 
     ELSE IF (@@ROWCOUNT = 0) 
       BEGIN 
      UPDATE NOTIFICATION SET TOKEN = @T, USTAMP = DATEADD(HH, 3, GETDATE()) WHERE UID = @U -- handle a token update 
       END 
    IF (@@ROWCOUNT=0 AND @PAIR =0) -- Last Resort 
      BEGIN 
      DELETE FROM NOTIFICATION WHERE TOKEN = @T OR UID = @U -- delete Token and User Id 
      INSERT INTO NOTIFICATION(TOKEN, UID, USTAMP, ISTAMP) VALUES (@T, @U, DATEADD(HH, 3, GETDATE()), DATEADD(HH, 3, GETDATE())) --Insert new pair 
       END 
    IF (@@ROWCOUNT > 0) 
       BEGIN 
       SET @RESULT = '1' 
       END 
     ELSE IF (@@ROWCOUNT=0 AND @PAIR =0) 
       BEGIN 
       SET @RESULT = '0' 
       END 

    SELECT @RESULT 
END 
+0

Ich hoffe, dass es für Sie gelöst hat. Es gibt Möglichkeiten, den Code zu vereinfachen, aber es scheint, dass uns hier eine klare Beschreibung der Geschäftsregeln fehlt, d. H. Wenn ein Benutzer versucht, mit einem anderen Gerät zu koppeln, was möchten Sie tun? –

+0

Ich möchte dem Benutzer erlauben, mit einem anderen Gerät zu koppeln. Ziel ist es, das letzte vom Benutzer verwendete Gerät im Auge zu behalten. :) –