Hey Mark,
I put this together quickly, so I hope I didn’t miss anything. This is an example of how to use the client side.
import anvil.server
from anvil import *
from anvil.js.window import history, location
if history.state is not None or "url" not in history.state:
state = {"url": location.hash, "pos": 0}
history.replaceState(state, "", state["url"])
from Firebase.client import ActionMap, FirebaseClient, FirebaseConfig
from Firebase.messages import (
Message,
MulticastMessage,
SimpleMessage,
WebpushConfig,
WebpushFCMOptions,
WebpushNotification,
WebpushNotificationAction,
)
from ._anvil_designer import MainTemplate
PUBLIC_VAPID_KEY = anvil.server.call("get_public_vapid_key")
APP_URL = anvil.server.get_app_origin("published")
BELL_ICON = "https://cdn.pixabay.com/photo/2015/12/16/17/41/bell-1096280_960_720.png"
STOCK_IMAGE = "https://mobileroadie.com/blog/wp-content/uploads/2019/10/what-is-push-notifications-cover.jpg"
GOOGLE_ICON = "https://c0.klipartz.com/pngpicture/669/506/gratis-png-google-chrome-logo-complemento-de-la-extension-del-navegador-del-navegador-web-google-chrome-chrome-google-logotipo-icono-social-thumbnail.png"
MY_TOPIC = "your_topic_name"
class Main(MainTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run before the form opens.
# --- PUBLIC METHODS ---
def initilaize_app(self, **event_args):
# You will need to initialize your Firebase app after the form is shown on the page.
# initialize the Firebase config. You can find this in the Firebase console.
firebase_config = FirebaseConfig.from_dict(
{
"apiKey": "__your_api_key__",
"authDomain": "__your_auth_domain__",
"projectId": "__your_project_id__",
"storageBucket": "__your_storage_bucket__",
"messagingSenderId": "__your_messaging_sender_id__",
"appId": "__your_app_id__",
"measurementId": "__your_measurement_id__",
}
)
# instantiate the Firebase Client
self.client = FirebaseClient(
config=firebase_config,
public_vapid_key=PUBLIC_VAPID_KEY,
message_handler=self.handle_message,
subscribe_handler=self.handle_subscribe,
unsubscribe_handler=self.handle_unsubscribe,
save_token_handler=self.handle_save_token,
topics=MY_TOPIC,
with_logging=False,
)
# initialize the Firebase app
self.client.initialize_app()
# request permission to send notifications
granted = self.client.request_notification_permission()
print(f"Notifications Granted: {granted}")
# --- EVENT HANDLERS ---
def get_client(self, **event_args):
try:
return self.client
except Exception:
return None
def handle_message(self, message):
"""Handle a message from Firebase"""
print(f"Message Recieved: {message}")
def handle_subscribe(self, topic: str, token: str):
"""Handle a subscribe event from Firebase"""
response = anvil.server.call(
"subscribe_to_topic",
topic=topic,
token=token,
)
print(response)
def handle_unsubscribe(self, topic: str, token: str):
"""Handle an unsubscribe event from Firebase"""
print(f"Unsubscribed from: {topic}")
def handle_save_token(self, token: str):
"""Handle a save token event from Firebase"""
print(f"Saved token: {token}")
# --- FORM EVENTS ---
def form_show(self, **event_args):
"""This method is called when the form is shown on the page"""
self.initilaize_app()
# --- USE EXAMPLES ---
def button_message_click(self, **event_args):
"""This method is called when the button is clicked"""
# Create a WebpushNotification object with the desired properties
notification = WebpushNotification(
title="New Message",
body="You have a new message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
)
# Define the link for the WebpushFCMOptions
link = f"{APP_URL}/#action"
# Create a WebpushFCMOptions object with the defined link
options = WebpushFCMOptions(link=link)
# Create a WebpushConfig object with the notification and options
webpush = WebpushConfig(
notification=notification,
fcm_options=options,
)
# Create a Message object with the webpush configuration and the client token
message = Message(
webpush=webpush,
token=self.client.token,
)
# Call the server function to send the message and store the response
task = anvil.server.call("send_message", message=message)
self.add_task(task)
def button_topic_message_click(self, **event_args):
"""This method is called when the button is clicked"""
# Create a WebpushNotification object with the desired properties
notification = WebpushNotification(
title="New Topic Message",
body="You have a new topic message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
)
# Define the link for the WebpushFCMOptions
link = f"{APP_URL}/#action"
# Create a WebpushFCMOptions object with the defined link
options = WebpushFCMOptions(link=link)
# Create a WebpushConfig object with the notification and options
webpush = WebpushConfig(
notification=notification,
fcm_options=options,
)
# Create a Message object with the webpush configuration and the topic
message = Message(
webpush=webpush,
topic=MY_TOPIC,
)
# Call the server function to send the message and store the response
task = anvil.server.call("send_message", message=message)
self.add_task(task)
def button_simple_message_click(self, **event_args):
"""This method is called when the button is clicked"""
# Create a SimpleMessage object with the desired properties
message = SimpleMessage(
title="New Simple Message",
body="You have a new simple message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
token=self.client.token,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
link=f"{APP_URL}/#action",
)
# Call the server function to send the message and store the response
task = anvil.server.call("send_message", message=message)
self.add_task(task)
def button_multicast_message_click(self, **event_args):
"""This method is called when the button is clicked"""
# Create a WebpushNotification object with the desired properties
notification = WebpushNotification(
title="New Multicast Message",
body="You have a new multi-cast message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
)
# Define the link for the WebpushFCMOptions
link = f"{APP_URL}/#action"
# Create a WebpushFCMOptions object with the defined link
options = WebpushFCMOptions(link=link)
# Create a WebpushConfig object with the notification and options
webpush = WebpushConfig(
notification=notification,
fcm_options=options,
)
# Create a MulticastMessage object with the webpush configuration and the client tokens
message = MulticastMessage(
webpush=webpush,
tokens=[self.client.token],
)
# Call the server function to send the multicast message and store the response
response = anvil.server.call("send_multicast_message", message=message)
# Print the response
print(f"Response: {response}")
def button_send_multi_messages_click(self, **event_args):
"""This method is called when the button is clicked"""
# Create a WebpushNotification object with the desired properties
notification = WebpushNotification(
title="New Topic Message",
body="You have a new topic message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
)
# Define the link for the WebpushFCMOptions
link = f"{APP_URL}/#action"
# Create a WebpushFCMOptions object with the defined link
options = WebpushFCMOptions(link=link)
# Create a WebpushConfig object with the notification and options
webpush = WebpushConfig(
notification=notification,
fcm_options=options,
)
# Create a Message object with the webpush configuration and the topic
message1 = Message(
webpush=webpush,
topic=MY_TOPIC,
)
# Create a SimpleMessage object with the desired properties
message2 = SimpleMessage(
title="New Simple Message",
body="You have a new simple message from your example app.",
icon=BELL_ICON,
image=STOCK_IMAGE,
token=self.client.token,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
link=f"{APP_URL}/#action",
)
# Combine the messages into a list
messages = [message1, message2]
# Call the server function to send the multiple messages and store the response
response = anvil.server.call("send_multiple_messages", messages)
# Print the response
print(f"Response: {response}")
def button_action_message_1_click(self, **event_args):
"""This method is called when the button is clicked"""
# Define the action title and endpoint
action_title = "open_action"
endpoint = "/#action"
# Create the full URL for the action
link_url = f"{APP_URL}{endpoint}"
# Create an ActionMap object with the action name, full URL, and API endpoint flag
action_map = ActionMap(
action_name=action_title, full_url=link_url, is_api_endpoint=False
)
# Add the action map to the client
self.client.add_action_map(action_map)
# Create a WebpushNotificationAction object with the action title
action = WebpushNotificationAction(
action=action_title,
title="Open Action",
)
# Create a WebpushNotification object with the desired properties and the action
notification = WebpushNotification(
title="New Action Message",
body="You have a new ACTION message from your example app.",
icon=BELL_ICON,
data={"temp": 70.6},
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
actions=[action],
)
# Create a WebpushFCMOptions object with the link URL
options = WebpushFCMOptions(link=link_url)
# Create a WebpushConfig object with the notification and options
webpush = WebpushConfig(notification=notification, fcm_options=options)
# Create a Message object with the webpush configuration and the client token
message = Message(
webpush=webpush,
token=self.client.token,
)
# Call the server function to send the message and store the response
response = anvil.server.call("send_message", message=message)
# Print the response
print(f"Response: {response}")
def button_action_message_2_click(self, **event_args):
"""This method is called when the button is clicked"""
# Define the action title and endpoint
action_title = "mark_read"
endpoint = "/mark-read" # Use just the relative path
# Create an ActionMap object with the action name, endpoint, data, and API endpoint flag
action_map = ActionMap(
action_name=action_title,
endpoint=endpoint,
data={"message_id": "test_message_id"},
is_api_endpoint=True,
)
# Add the action map to the client
self.client.add_action_map(action_map)
# Create a WebpushNotificationAction object with the action title
action = WebpushNotificationAction(
action=action_title,
title="Mark As Read",
)
# Create a WebpushNotification object with the desired properties and the action
notification = WebpushNotification(
title="New Action Message",
body="You have a new ACTION message from your example app.",
icon=BELL_ICON,
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
actions=[action],
)
# Create a WebpushConfig object with the notification
webpush = WebpushConfig(
notification=notification,
)
# Create a Message object with the webpush configuration and the client token
message = Message(
webpush=webpush,
token=self.client.token,
)
# Call the server function to send the message and store the response
response = anvil.server.call("send_message", message=message)
# Print the response
print(f"Response: {response}")
def button_action_message_3_click(self, **event_args):
"""This method is called when the button is clicked"""
# Define the action title and endpoint
action_title = "mark_unread"
endpoint = "/mark-unread"
# Create an ActionMap object with the action name, endpoint, parameters, and API endpoint flag
action_map = ActionMap(
action_name=action_title,
endpoint=endpoint,
params={"message_id": "test_message_id"},
is_api_endpoint=True,
)
# Add the action map to the client
self.client.add_action_map(action_map)
# Create a WebpushNotificationAction object with the action title
action = WebpushNotificationAction(
action=action_title,
title="Mark As Unread",
)
# Create a WebpushNotification object with the desired properties and the action
notification = WebpushNotification(
title="New Action Message",
body="You have a new ACTION message from your example app.",
icon=BELL_ICON,
silent=False,
vibrate=["0.0s", "0.2s", "0.1s", "0.2s"],
actions=[action],
)
# Create a WebpushConfig object with the notification
webpush = WebpushConfig(
notification=notification,
)
# Create a Message object with the webpush configuration and the client token
message = Message(
webpush=webpush,
token=self.client.token,
)
# Call the server function to send the message and store the response
response = anvil.server.call("send_message", message=message)
# Print the response
print(f"Response: {response}")
def add_task(self, task):
task_id = task.get_id()
if task_id not in self.tasks:
self.tasks[task_id] = task
self.timer_1.interval = 0.5
def timer_1_tick(self, **event_args):
"""
This method is called Every [interval] seconds. Does not trigger if [interval] is 0.
It checks for completed tasks and removes them from the tasks dictionary.
"""
with anvil.server.no_loading_indicator:
completed_tasks = [
task_id for task_id, task in self.tasks.items() if task.is_completed()
]
for task_id in completed_tasks:
response = self.tasks[task_id].get_return_value()
print(f"Response: {response}")
del self.tasks[task_id]
if not self.tasks:
self.timer_1.interval = 0
Let me know if I can help with anything else. Sorry if I’m slow in responding, I don’t always see these messages when I’m focused in on my fulltime.