diff --git a/backend/src/baserow/contrib/database/apps.py b/backend/src/baserow/contrib/database/apps.py
index c1a8767f2..3ac89d311 100755
--- a/backend/src/baserow/contrib/database/apps.py
+++ b/backend/src/baserow/contrib/database/apps.py
@@ -686,6 +686,7 @@ class DatabaseConfig(AppConfig):
         object_scope_type_registry.register(TokenObjectScopeType())
 
         from baserow.contrib.database.views.operations import (
+            CanReceiveNotificationOnSubmitFormViewOperationType,
             UpdateViewFieldOptionsOperationType,
         )
 
@@ -826,6 +827,9 @@ class DatabaseConfig(AppConfig):
         operation_type_registry.register(CreateAndUsePersonalViewOperationType())
         operation_type_registry.register(ReadViewOperationType())
         operation_type_registry.register(UpdateViewOperationType())
+        operation_type_registry.register(
+            CanReceiveNotificationOnSubmitFormViewOperationType()
+        )
         operation_type_registry.register(DeleteViewOperationType())
         operation_type_registry.register(DuplicateViewOperationType())
         operation_type_registry.register(CreateViewFilterOperationType())
diff --git a/backend/src/baserow/contrib/database/views/handler.py b/backend/src/baserow/contrib/database/views/handler.py
index 6e4bac539..70c831a4d 100644
--- a/backend/src/baserow/contrib/database/views/handler.py
+++ b/backend/src/baserow/contrib/database/views/handler.py
@@ -75,7 +75,6 @@ from baserow.contrib.database.views.operations import (
     UpdateViewFilterGroupOperationType,
     UpdateViewFilterOperationType,
     UpdateViewGroupByOperationType,
-    UpdateViewOperationType,
     UpdateViewPublicOperationType,
     UpdateViewSlugOperationType,
     UpdateViewSortOperationType,
@@ -947,7 +946,7 @@ class ViewHandler(metaclass=baserow_trace_methods(tracer)):
 
         :param user: The user on whose behalf the view is updated.
         :param view: The view instance that needs to be updated.
-        :param data: The fields that need to be updated.
+        :param data: The properties that need to be updated.
         :raises ValueError: When the provided view not an instance of View.
         :return: The updated view instance.
         """
@@ -955,16 +954,12 @@ class ViewHandler(metaclass=baserow_trace_methods(tracer)):
         if not isinstance(view, View):
             raise ValueError("The view is not an instance of View.")
 
-        workspace = view.table.database.workspace
-        CoreHandler().check_permissions(
-            user, UpdateViewOperationType.type, workspace=workspace, context=view
-        )
+        view_type = view_type_registry.get_by_model(view)
+        view_type.check_view_update_permissions(user, view, data)
+        view_type.before_view_update(data, view, user)
 
         old_view = deepcopy(view)
 
-        view_type = view_type_registry.get_by_model(view)
-        view_type.before_view_update(data, view, user)
-
         view_values = view_type.prepare_values(data, view.table, user)
         allowed_fields = [
             "name",
@@ -1003,6 +998,7 @@ class ViewHandler(metaclass=baserow_trace_methods(tracer)):
         )
         view = set_allowed_attrs(view_values, allowed_attrs, view)
         if previous_public_value != view.public:
+            workspace = view.table.database.workspace
             CoreHandler().check_permissions(
                 user,
                 UpdateViewPublicOperationType.type,
diff --git a/backend/src/baserow/contrib/database/views/notification_types.py b/backend/src/baserow/contrib/database/views/notification_types.py
index e8de2c338..783f2a044 100644
--- a/backend/src/baserow/contrib/database/views/notification_types.py
+++ b/backend/src/baserow/contrib/database/views/notification_types.py
@@ -6,7 +6,9 @@ from django.dispatch import receiver
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 
-from baserow.contrib.database.views.operations import UpdateViewOperationType
+from baserow.contrib.database.views.operations import (
+    CanReceiveNotificationOnSubmitFormViewOperationType,
+)
 from baserow.core.handler import CoreHandler
 from baserow.core.notifications.handler import NotificationHandler
 from baserow.core.notifications.registries import (
@@ -116,7 +118,7 @@ def create_form_submitted_notification(sender, form, row, values, user, **kwargs
     # Ensure all users still have permissions on the table to see the notification
     allowed_users = CoreHandler().check_permission_for_multiple_actors(
         users_to_notify,
-        UpdateViewOperationType.type,
+        CanReceiveNotificationOnSubmitFormViewOperationType.type,
         workspace=form.table.database.workspace,
         context=form,
     )
diff --git a/backend/src/baserow/contrib/database/views/operations.py b/backend/src/baserow/contrib/database/views/operations.py
index 395795685..65e371ad5 100644
--- a/backend/src/baserow/contrib/database/views/operations.py
+++ b/backend/src/baserow/contrib/database/views/operations.py
@@ -124,6 +124,10 @@ class UpdateViewOperationType(ViewOperationType):
     type = "database.table.view.update"
 
 
+class CanReceiveNotificationOnSubmitFormViewOperationType(ViewOperationType):
+    type = "database.table.view.can_receive_notification_on_submit_form_view"
+
+
 class DeleteViewOperationType(ViewOperationType):
     type = "database.table.view.delete"
 
diff --git a/backend/src/baserow/contrib/database/views/registries.py b/backend/src/baserow/contrib/database/views/registries.py
index 7e33896bc..6fd7eaa0d 100644
--- a/backend/src/baserow/contrib/database/views/registries.py
+++ b/backend/src/baserow/contrib/database/views/registries.py
@@ -23,6 +23,7 @@ from rest_framework.serializers import Serializer
 
 from baserow.contrib.database.fields.field_filters import OptionallyAnnotatedQ
 from baserow.core.exceptions import PermissionDenied
+from baserow.core.handler import CoreHandler
 from baserow.core.models import Workspace, WorkspaceUser
 from baserow.core.registries import OperationType
 from baserow.core.registry import (
@@ -837,6 +838,29 @@ class ViewType(
             },
         )
 
+    def check_view_update_permissions(
+        self, user: AbstractUser, view: "View", data: Dict[str, Any]
+    ):
+        """
+        Hook that's called just before a view is updated. By default, it checks the
+        `UpdateViewOperationType`, but when overwritten, it can optionally check for
+        different permissions depending on the data. It returns nothing if the user has
+        permissions, or raises a PermissionDenied error otherwise.
+
+        :param user: The user on whose behalf the view is updated.
+        :param view: The view instance that needs to be updated.
+        :param data: The properties that need to be updated.
+        :raises PermissionDenied: if the user doesn't have permissions to update the
+            view.
+        """
+
+        from .operations import UpdateViewOperationType
+
+        workspace = view.table.database.workspace
+        CoreHandler().check_permissions(
+            user, UpdateViewOperationType.type, workspace=workspace, context=view
+        )
+
 
 class ViewTypeRegistry(
     APIUrlsRegistryMixin, CustomFieldsRegistryMixin, ModelRegistryMixin, Registry
diff --git a/backend/src/baserow/contrib/database/views/view_types.py b/backend/src/baserow/contrib/database/views/view_types.py
index 573f3045a..a8b01374e 100644
--- a/backend/src/baserow/contrib/database/views/view_types.py
+++ b/backend/src/baserow/contrib/database/views/view_types.py
@@ -46,6 +46,7 @@ from baserow.contrib.database.fields.models import Field, FileField, SelectOptio
 from baserow.contrib.database.fields.registries import field_type_registry
 from baserow.contrib.database.table.models import Table
 from baserow.contrib.database.views.registries import view_aggregation_type_registry
+from baserow.core.handler import CoreHandler
 from baserow.core.import_export.utils import file_chunk_generator
 from baserow.core.storage import ExportZipFile
 from baserow.core.user_files.handler import UserFileHandler
@@ -1403,3 +1404,26 @@ class FormViewType(ViewType):
         return FormViewFieldOptions(
             field_id=field_id, form_view_id=view.id, enabled=False
         )
+
+    def check_view_update_permissions(self, user, view, data):
+        from .operations import CanReceiveNotificationOnSubmitFormViewOperationType
+
+        workspace = view.table.database.workspace
+
+        if "receive_notification_on_submit" in data:
+            # If `receive_notification_on_submit` is in the data, then we must check if
+            # the user has permissions to receive a notification on submit.
+            CoreHandler().check_permissions(
+                user,
+                CanReceiveNotificationOnSubmitFormViewOperationType.type,
+                workspace=workspace,
+                context=view,
+            )
+
+            # If only the `receive_notification_on_submit` is provided, then there is
+            # no need to check if the user has permissions to update the view because
+            # nothing else is changed.
+            if len(data) == 1:
+                return
+
+        return super().check_view_update_permissions(user, view, data)
diff --git a/changelog/entries/unreleased/bug/3271_allow_editors_to_subscribe_to_a_form_view.json b/changelog/entries/unreleased/bug/3271_allow_editors_to_subscribe_to_a_form_view.json
new file mode 100644
index 000000000..a20bfe7f1
--- /dev/null
+++ b/changelog/entries/unreleased/bug/3271_allow_editors_to_subscribe_to_a_form_view.json
@@ -0,0 +1,7 @@
+{
+  "type": "bug",
+  "message": "Allow editors to subscribe to a form view.",
+  "issue_number": 3271,
+  "bullet_points": [],
+  "created_at": "2025-01-18"
+}
diff --git a/enterprise/backend/src/baserow_enterprise/role/default_roles.py b/enterprise/backend/src/baserow_enterprise/role/default_roles.py
index 3397192c9..60d85fb7d 100755
--- a/enterprise/backend/src/baserow_enterprise/role/default_roles.py
+++ b/enterprise/backend/src/baserow_enterprise/role/default_roles.py
@@ -126,6 +126,7 @@ from baserow.contrib.database.tokens.operations import (
     UseTokenOperationType,
 )
 from baserow.contrib.database.views.operations import (
+    CanReceiveNotificationOnSubmitFormViewOperationType,
     CreateAndUsePersonalViewOperationType,
     CreatePublicViewOperationType,
     CreateViewDecorationOperationType,
@@ -347,6 +348,7 @@ default_roles[EDITOR_ROLE_UID].extend(
         RestoreDatabaseRowOperationType,
         ListTeamSubjectsOperationType,
         ReadTeamSubjectOperationType,
+        CanReceiveNotificationOnSubmitFormViewOperationType,
     ]
 )
 default_roles[BUILDER_ROLE_UID].extend(
diff --git a/enterprise/backend/tests/baserow_enterprise_tests/role/test_view_permissions.py b/enterprise/backend/tests/baserow_enterprise_tests/role/test_view_permissions.py
new file mode 100644
index 000000000..80f0dce80
--- /dev/null
+++ b/enterprise/backend/tests/baserow_enterprise_tests/role/test_view_permissions.py
@@ -0,0 +1,68 @@
+from django.test import override_settings
+
+import pytest
+
+from baserow.contrib.database.views.handler import ViewHandler
+from baserow.core.exceptions import PermissionDenied
+from baserow_enterprise.role.handler import RoleAssignmentHandler
+
+
+@pytest.mark.django_db
+@override_settings(DEBUG=True)
+def test_update_form_view_as_editor_fails(enterprise_data_fixture):
+    enterprise_data_fixture.enable_enterprise()
+    user, token = enterprise_data_fixture.create_user_and_token(
+        email="test@test.nl", password="password", first_name="Test1"
+    )
+    table = enterprise_data_fixture.create_database_table(user)
+    form = enterprise_data_fixture.create_form_view(table=table)
+    editor_role = RoleAssignmentHandler().get_role_by_uid("EDITOR")
+    RoleAssignmentHandler().assign_role(
+        user, table.database.workspace, role=editor_role, scope=table
+    )
+
+    handler = ViewHandler()
+
+    with pytest.raises(PermissionDenied):
+        handler.update_view(user=user, view=form, name="Test 1")
+
+
+@pytest.mark.django_db
+@override_settings(DEBUG=True)
+def test_update_form_view_notification_as_editor_succeeds(enterprise_data_fixture):
+    enterprise_data_fixture.enable_enterprise()
+    user, token = enterprise_data_fixture.create_user_and_token(
+        email="test@test.nl", password="password", first_name="Test1"
+    )
+    table = enterprise_data_fixture.create_database_table(user)
+    form = enterprise_data_fixture.create_form_view(table=table)
+    editor_role = RoleAssignmentHandler().get_role_by_uid("EDITOR")
+    RoleAssignmentHandler().assign_role(
+        user, table.database.workspace, role=editor_role, scope=table
+    )
+
+    handler = ViewHandler()
+    handler.update_view(user=user, view=form, receive_notification_on_submit=True)
+    assert form.users_to_notify_on_submit.count() == 1
+
+
+@pytest.mark.django_db
+@override_settings(DEBUG=True)
+def test_update_form_view_and_notification_as_editor_fails(enterprise_data_fixture):
+    enterprise_data_fixture.enable_enterprise()
+    user, token = enterprise_data_fixture.create_user_and_token(
+        email="test@test.nl", password="password", first_name="Test1"
+    )
+    table = enterprise_data_fixture.create_database_table(user)
+    form = enterprise_data_fixture.create_form_view(table=table)
+    editor_role = RoleAssignmentHandler().get_role_by_uid("EDITOR")
+    RoleAssignmentHandler().assign_role(
+        user, table.database.workspace, role=editor_role, scope=table
+    )
+
+    handler = ViewHandler()
+
+    with pytest.raises(PermissionDenied):
+        handler.update_view(
+            user=user, view=form, receive_notification_on_submit=True, name="Test"
+        )
diff --git a/premium/backend/src/baserow_premium/permission_manager.py b/premium/backend/src/baserow_premium/permission_manager.py
index 6b2f820b0..a63cf6e72 100644
--- a/premium/backend/src/baserow_premium/permission_manager.py
+++ b/premium/backend/src/baserow_premium/permission_manager.py
@@ -9,6 +9,7 @@ from baserow_premium.views.models import OWNERSHIP_TYPE_PERSONAL
 
 from baserow.contrib.database.table.models import Table
 from baserow.contrib.database.views.operations import (
+    CanReceiveNotificationOnSubmitFormViewOperationType,
     CreateAndUsePersonalViewOperationType,
     CreateViewDecorationOperationType,
     CreateViewFilterGroupOperationType,
@@ -91,6 +92,7 @@ class ViewOwnershipPermissionManagerType(PermissionManagerType):
             DeleteViewSortOperationType.type,
             ReadViewOperationType.type,
             UpdateViewOperationType.type,
+            CanReceiveNotificationOnSubmitFormViewOperationType.type,
             DeleteViewOperationType.type,
             DuplicateViewOperationType.type,
             CreateViewFilterOperationType.type,
diff --git a/web-frontend/modules/database/components/view/form/FormViewMetaControls.vue b/web-frontend/modules/database/components/view/form/FormViewMetaControls.vue
index 027338edf..5e8ce7104 100644
--- a/web-frontend/modules/database/components/view/form/FormViewMetaControls.vue
+++ b/web-frontend/modules/database/components/view/form/FormViewMetaControls.vue
@@ -1,6 +1,13 @@
 <template>
   <div class="form-view__meta-controls">
     <SwitchInput
+      v-if="
+        $hasPermission(
+          'database.table.view.can_receive_notification_on_submit_form_view',
+          view,
+          database.workspace.id
+        )
+      "
       small
       :value="view.receive_notification_on_submit"
       class="margin-bottom-3"